v / vlib / v2 / gen / x64 / x64_runtime_smoke_test.v
7413 lines · 6522 sloc · 194.23 KB
Raw
1module x64
2
3import encoding.binary
4import os
5
6struct X64LinuxRunResult {
7 stdout []u8
8 stderr []u8
9}
10
11struct X64LinuxRunExitResult {
12 stdout []u8
13 stderr []u8
14 exit_code int
15}
16
17struct X64HostRunResult {
18 name string
19 tmp_dir string
20 source_path string
21 source_text string
22 bin_path string
23 build_output string
24 stdout []u8
25 stderr []u8
26}
27
28struct X64HostRunExitResult {
29 name string
30 tmp_dir string
31 source_path string
32 source_text string
33 bin_path string
34 build_output string
35 stdout []u8
36 stderr []u8
37 exit_code int
38}
39
40struct X64ElfLoadSegment {
41 offset u64
42 vaddr u64
43 flags u32
44 filesz u64
45 memsz u64
46 align u64
47}
48
49fn run_x64_linux_program_redirected(name string, source string) X64LinuxRunResult {
50 tmp_dir := os.join_path(os.vtmp_dir(), 'v2_x64_runtime_${name}_${os.getpid()}')
51 os.mkdir_all(tmp_dir) or { panic(err) }
52 defer {
53 os.rmdir_all(tmp_dir) or {}
54 }
55 source_path := os.join_path(tmp_dir, '${name}.v')
56 bin_path := os.join_path(tmp_dir, name)
57 stdout_path := os.join_path(tmp_dir, '${name}.out')
58 stderr_path := os.join_path(tmp_dir, '${name}.err')
59 os.write_file(source_path, source) or { panic(err) }
60 vexe := os.getenv_opt('VEXE') or { @VEXE }
61 build :=
62 os.execute('${os.quoted_path(vexe)} -v2 -no-parallel -b x64 ${os.quoted_path(source_path)} -o ${os.quoted_path(bin_path)}')
63 assert build.exit_code == 0, '${name} build failed:\n${build.output}'
64 run :=
65 os.execute('${os.quoted_path(bin_path)} > ${os.quoted_path(stdout_path)} 2> ${os.quoted_path(stderr_path)}')
66 assert run.exit_code == 0, '${name} run failed:\n${run.output}'
67 stdout := os.read_bytes(stdout_path) or { panic(err) }
68 stderr := os.read_bytes(stderr_path) or { panic(err) }
69 return X64LinuxRunResult{
70 stdout: stdout
71 stderr: stderr
72 }
73}
74
75fn run_x64_linux_program_redirected_with_exit(name string, source string) X64LinuxRunExitResult {
76 tmp_dir := os.join_path(os.vtmp_dir(), 'v2_x64_runtime_${name}_${os.getpid()}')
77 os.mkdir_all(tmp_dir) or { panic(err) }
78 defer {
79 os.rmdir_all(tmp_dir) or {}
80 }
81 source_path := os.join_path(tmp_dir, '${name}.v')
82 bin_path := os.join_path(tmp_dir, name)
83 stdout_path := os.join_path(tmp_dir, '${name}.out')
84 stderr_path := os.join_path(tmp_dir, '${name}.err')
85 os.write_file(source_path, source) or { panic(err) }
86 vexe := os.getenv_opt('VEXE') or { @VEXE }
87 build :=
88 os.execute('${os.quoted_path(vexe)} -v2 -no-parallel -b x64 ${os.quoted_path(source_path)} -o ${os.quoted_path(bin_path)}')
89 assert build.exit_code == 0, '${name} build failed:\n${build.output}'
90 run :=
91 os.execute('${os.quoted_path(bin_path)} > ${os.quoted_path(stdout_path)} 2> ${os.quoted_path(stderr_path)}')
92 stdout := os.read_bytes(stdout_path) or { panic(err) }
93 stderr := os.read_bytes(stderr_path) or { panic(err) }
94 return X64LinuxRunExitResult{
95 stdout: stdout
96 stderr: stderr
97 exit_code: run.exit_code
98 }
99}
100
101fn run_x64_linux_project_redirected(name string, sources map[string]string) X64LinuxRunResult {
102 tmp_dir := os.join_path(os.vtmp_dir(), 'v2_x64_runtime_${name}_${os.getpid()}')
103 os.mkdir_all(tmp_dir) or { panic(err) }
104 defer {
105 os.rmdir_all(tmp_dir) or {}
106 }
107 bin_path := os.join_path(tmp_dir, name)
108 stdout_path := os.join_path(tmp_dir, '${name}.out')
109 stderr_path := os.join_path(tmp_dir, '${name}.err')
110 for rel_path, source in sources {
111 source_path := os.join_path(tmp_dir, rel_path)
112 os.mkdir_all(os.dir(source_path)) or { panic(err) }
113 os.write_file(source_path, source) or { panic(err) }
114 }
115 vexe := os.getenv_opt('VEXE') or { @VEXE }
116 build :=
117 os.execute('${os.quoted_path(vexe)} -v2 -no-parallel -b x64 ${os.quoted_path(tmp_dir)} -o ${os.quoted_path(bin_path)}')
118 assert build.exit_code == 0, '${name} build failed:\n${build.output}'
119 run :=
120 os.execute('${os.quoted_path(bin_path)} > ${os.quoted_path(stdout_path)} 2> ${os.quoted_path(stderr_path)}')
121 assert run.exit_code == 0, '${name} run failed:\n${run.output}'
122 stdout := os.read_bytes(stdout_path) or { panic(err) }
123 stderr := os.read_bytes(stderr_path) or { panic(err) }
124 return X64LinuxRunResult{
125 stdout: stdout
126 stderr: stderr
127 }
128}
129
130fn x64_vexe_command_path() string {
131 vexe := os.getenv_opt('VEXE') or { @VEXE }
132 if os.is_abs_path(vexe) || !os.exists(vexe) {
133 return vexe
134 }
135 return os.abs_path(vexe)
136}
137
138fn x64_build_file_from_dir(vexe string, source_dir string, source_file string, bin_path string) os.Result {
139 mut build := os.new_process(vexe)
140 defer {
141 build.close()
142 }
143 build.set_work_folder(source_dir)
144 build.set_environment(x64_pinned_v2_build_environment(vexe, os.dir(bin_path)))
145 build.set_args(['-v2', '-no-parallel', '-b', 'x64', source_file, '-o', bin_path])
146 build.set_redirect_stdio()
147 build.run()
148 build.wait()
149 stdout := build.stdout_slurp()
150 stderr := build.stderr_slurp()
151 return os.Result{
152 exit_code: build.code
153 output: 'stdout:\n${stdout}\nstderr:\n${stderr}'
154 }
155}
156
157fn run_x64_linux_file_redirected(name string, source_dir string, source_file string) X64LinuxRunResult {
158 tmp_dir := os.join_path(os.vtmp_dir(), 'v2_x64_runtime_${name}_${os.getpid()}')
159 os.mkdir_all(tmp_dir) or { panic(err) }
160 defer {
161 os.rmdir_all(tmp_dir) or {}
162 }
163 source_path := os.join_path(source_dir, source_file)
164 bin_path := os.join_path(tmp_dir, name)
165 stdout_path := os.join_path(tmp_dir, '${name}.out')
166 stderr_path := os.join_path(tmp_dir, '${name}.err')
167 vexe := x64_vexe_command_path()
168 build := x64_build_file_from_dir(vexe, source_dir, source_file, bin_path)
169 assert build.exit_code == 0, '${name} build failed for ${source_path}:\n${build.output}'
170 run :=
171 os.execute('${os.quoted_path(bin_path)} > ${os.quoted_path(stdout_path)} 2> ${os.quoted_path(stderr_path)}')
172 assert run.exit_code == 0, '${name} run failed:\n${run.output}'
173 stdout := os.read_bytes(stdout_path) or { panic(err) }
174 stderr := os.read_bytes(stderr_path) or { panic(err) }
175 return X64LinuxRunResult{
176 stdout: stdout
177 stderr: stderr
178 }
179}
180
181fn x64_host_bin_path(tmp_dir string, name string) string {
182 mut bin_name := name
183 $if windows {
184 bin_name += '.exe'
185 }
186 return os.join_path(tmp_dir, bin_name)
187}
188
189fn x64_runtime_bytes_report(label string, bytes []u8) string {
190 return '${label} bytes: ${bytes}\n${label} text: ${bytes.bytestr()}'
191}
192
193fn x64_runtime_exit_code_report(exit_code int) string {
194 return '${exit_code} (u32 0x${u32(exit_code).hex_full().to_upper()})'
195}
196
197fn x64_runtime_tmp_listing(tmp_dir string) string {
198 entries := os.ls(tmp_dir) or { return 'tmp listing unavailable: ${err}' }
199 return entries.str()
200}
201
202fn x64_host_cleanup_tmp(tmp_dir string) {
203 os.rmdir_all(tmp_dir) or {}
204}
205
206fn x64_host_context(name string, tmp_dir string, source_path string, bin_path string) string {
207 return 'name: ${name}\ntmp dir: ${tmp_dir}\nsource path: ${source_path}\nbin path: ${bin_path}\ntmp listing: ${x64_runtime_tmp_listing(tmp_dir)}'
208}
209
210fn x64_host_context_with_source(name string, tmp_dir string, source_path string, source_text string, bin_path string) string {
211 context := x64_host_context(name, tmp_dir, source_path, bin_path)
212 return '${context}\nsource text:\n${source_text}'
213}
214
215fn x64_host_build_failure_message(name string, tmp_dir string, source_path string, source_text string, bin_path string, build_exit_code int, build_output string) string {
216 source_context := x64_host_context_with_source(name, tmp_dir, source_path, source_text,
217 bin_path)
218 return '${source_context}\nbuild exit code: ${build_exit_code}\nbuild output:\n${build_output}'
219}
220
221fn x64_build_v2_delegate_for_tmp(vexe string, tmp_dir string) string {
222 v2_source := os.join_path(@VMODROOT, 'cmd', 'v2', 'v2.v')
223 v2_delegate := x64_host_bin_path(tmp_dir, 'v2_delegate')
224 build :=
225 os.execute('${os.quoted_path(vexe)} -o ${os.quoted_path(v2_delegate)} ${os.quoted_path(v2_source)}')
226 if build.exit_code != 0 {
227 assert false, 'failed to build v2 delegate for tiny x64 test:\n${build.output}'
228 }
229 return v2_delegate
230}
231
232fn x64_pinned_v2_build_environment(vexe string, tmp_dir string) map[string]string {
233 mut env := os.environ()
234 env.delete('V2_X64_LINUX_TINY')
235 env['V_V2_EXE'] = x64_build_v2_delegate_for_tmp(vexe, tmp_dir)
236 return env
237}
238
239fn x64_strict_tiny_build_environment(vexe string, tmp_dir string) map[string]string {
240 mut env := x64_pinned_v2_build_environment(vexe, tmp_dir)
241 env['V2_X64_LINUX_TINY'] = '1'
242 return env
243}
244
245fn x64_no_tiny_build_environment(vexe string, tmp_dir string) map[string]string {
246 return x64_pinned_v2_build_environment(vexe, tmp_dir)
247}
248
249fn x64_macos_auto_tiny_build_environment(vexe string, tmp_dir string) map[string]string {
250 return x64_pinned_v2_build_environment(vexe, tmp_dir)
251}
252
253fn x64_optional_tool_output(caller string, tool string, args string) ?string {
254 path := os.find_abs_path_of_executable(tool) or {
255 println('skipping ${caller} ${tool} assertions: ${tool} is not available')
256 return none
257 }
258 return os.execute('${os.quoted_path(path)} ${args}').output
259}
260
261fn x64_elf_load_segments(path string) []X64ElfLoadSegment {
262 data := os.read_bytes(path) or { panic(err) }
263 if data.len < 64 || data[0] != 0x7f || data[1] != `E` || data[2] != `L` || data[3] != `F`
264 || data[4] != 2 || data[5] != 1 {
265 panic('${path} is not an ELF64 little-endian file')
266 }
267 phoff := int(binary.little_endian_u64_at(data, 32))
268 phentsize := int(binary.little_endian_u16_at(data, 54))
269 phnum := int(binary.little_endian_u16_at(data, 56))
270 mut segments := []X64ElfLoadSegment{}
271 for i in 0 .. phnum {
272 off := phoff + i * phentsize
273 if off + 56 > data.len {
274 panic('${path} has a truncated ELF program header table')
275 }
276 if binary.little_endian_u32_at(data, off) == u32(pt_load) {
277 segments << X64ElfLoadSegment{
278 offset: binary.little_endian_u64_at(data, off + 8)
279 vaddr: binary.little_endian_u64_at(data, off + 16)
280 flags: binary.little_endian_u32_at(data, off + 4)
281 filesz: binary.little_endian_u64_at(data, off + 32)
282 memsz: binary.little_endian_u64_at(data, off + 40)
283 align: binary.little_endian_u64_at(data, off + 48)
284 }
285 }
286 }
287 return segments
288}
289
290fn x64_elf_load_segment_count(path string) int {
291 return x64_elf_load_segments(path).len
292}
293
294fn x64_host_run_failure_message(name string, tmp_dir string, source_path string, source_text string, bin_path string, build_output string, run_exit_code int, stdout []u8, stderr []u8) string {
295 context := x64_host_context_with_source(name, tmp_dir, source_path, source_text, bin_path)
296 stdout_report := x64_runtime_bytes_report('stdout', stdout)
297 stderr_report := x64_runtime_bytes_report('stderr', stderr)
298 run_exit_report := x64_runtime_exit_code_report(run_exit_code)
299 return '${context}\nbuild output:\n${build_output}\nrun exit code: ${run_exit_report}\n${stdout_report}\n${stderr_report}'
300}
301
302fn x64_host_result_context(result X64HostRunResult) string {
303 context := x64_host_context_with_source(result.name, result.tmp_dir, result.source_path,
304 result.source_text, result.bin_path)
305 return '${context}\nbuild output:\n${result.build_output}'
306}
307
308fn x64_host_exit_result_context(result X64HostRunExitResult) string {
309 context := x64_host_context_with_source(result.name, result.tmp_dir, result.source_path,
310 result.source_text, result.bin_path)
311 return '${context}\nbuild output:\n${result.build_output}'
312}
313
314fn x64_stdout_mismatch_message(name string, platform string, expected_stdout []u8, actual_stdout []u8, context string) string {
315 expected_report := x64_runtime_bytes_report('expected stdout', expected_stdout)
316 actual_report := x64_runtime_bytes_report('actual stdout', actual_stdout)
317 return '${name} ${platform} stdout mismatch\n${context}\n${expected_report}\n${actual_report}'
318}
319
320fn x64_stderr_mismatch_message(name string, platform string, expected_stderr []u8, actual_stderr []u8, context string) string {
321 expected_report := x64_runtime_bytes_report('expected stderr', expected_stderr)
322 actual_report := x64_runtime_bytes_report('actual stderr', actual_stderr)
323 return '${name} ${platform} stderr mismatch\n${context}\n${expected_report}\n${actual_report}'
324}
325
326fn x64_exit_code_mismatch_message(name string, platform string, expected_exit_code int, actual_exit_code int, stdout []u8, stderr []u8, context string) string {
327 stdout_report := x64_runtime_bytes_report('stdout', stdout)
328 stderr_report := x64_runtime_bytes_report('stderr', stderr)
329 expected_report := x64_runtime_exit_code_report(expected_exit_code)
330 actual_report := x64_runtime_exit_code_report(actual_exit_code)
331 return '${name} ${platform} exit code mismatch: expected ${expected_report}, got ${actual_report}\n${context}\n${stdout_report}\n${stderr_report}'
332}
333
334fn run_x64_host_program_redirected(name string, source string) X64HostRunResult {
335 tmp_dir := os.join_path(os.vtmp_dir(), 'v2_x64_runtime_${name}_${os.getpid()}')
336 os.mkdir_all(tmp_dir) or { panic(err) }
337 source_path := os.join_path(tmp_dir, '${name}.v')
338 bin_path := x64_host_bin_path(tmp_dir, name)
339 os.write_file(source_path, source) or { panic(err) }
340 vexe := os.getenv_opt('VEXE') or { @VEXE }
341 build :=
342 os.execute('${os.quoted_path(vexe)} -v2 -no-parallel -b x64 ${os.quoted_path(source_path)} -o ${os.quoted_path(bin_path)}')
343 if build.exit_code != 0 {
344 assert false, x64_host_build_failure_message(name, tmp_dir, source_path, source, bin_path,
345 build.exit_code, build.output)
346 }
347 mut run := os.new_process(bin_path)
348 defer {
349 run.close()
350 }
351 run.set_redirect_stdio()
352 run.run()
353 run.wait()
354 stdout := run.stdout_slurp().bytes()
355 stderr := run.stderr_slurp().bytes()
356 if run.code != 0 {
357 assert false, x64_host_run_failure_message(name, tmp_dir, source_path, source, bin_path,
358 build.output, run.code, stdout, stderr)
359 }
360 return X64HostRunResult{
361 name: name
362 tmp_dir: tmp_dir
363 source_path: source_path
364 source_text: source
365 bin_path: bin_path
366 build_output: build.output
367 stdout: stdout
368 stderr: stderr
369 }
370}
371
372fn run_x64_host_program_redirected_tiny(name string, source string) X64HostRunResult {
373 tmp_dir := os.join_path(os.vtmp_dir(), 'v2_x64_runtime_${name}_${os.getpid()}')
374 os.mkdir_all(tmp_dir) or { panic(err) }
375 source_path := os.join_path(tmp_dir, '${name}.v')
376 bin_path := x64_host_bin_path(tmp_dir, name)
377 os.write_file(source_path, source) or { panic(err) }
378 vexe := os.getenv_opt('VEXE') or { @VEXE }
379 mut build := os.new_process(vexe)
380 defer {
381 build.close()
382 }
383 build.set_environment(x64_strict_tiny_build_environment(vexe, tmp_dir))
384 build.set_args(['-v2', '-no-parallel', '-b', 'x64', source_path, '-o', bin_path])
385 build.set_redirect_stdio()
386 build.run()
387 build.wait()
388 build_output := 'stdout:\n${build.stdout_slurp()}\nstderr:\n${build.stderr_slurp()}'
389 if build.code != 0 {
390 assert false, x64_host_build_failure_message(name, tmp_dir, source_path, source, bin_path,
391 build.code, build_output)
392 }
393 mut run := os.new_process(bin_path)
394 defer {
395 run.close()
396 }
397 run.set_redirect_stdio()
398 run.run()
399 run.wait()
400 stdout := run.stdout_slurp().bytes()
401 stderr := run.stderr_slurp().bytes()
402 if run.code != 0 {
403 assert false, x64_host_run_failure_message(name, tmp_dir, source_path, source, bin_path,
404 build_output, run.code, stdout, stderr)
405 }
406 return X64HostRunResult{
407 name: name
408 tmp_dir: tmp_dir
409 source_path: source_path
410 source_text: source
411 bin_path: bin_path
412 build_output: build_output
413 stdout: stdout
414 stderr: stderr
415 }
416}
417
418fn run_x64_host_program_redirected_auto(name string, source string) X64HostRunResult {
419 tmp_dir := os.join_path(os.vtmp_dir(), 'v2_x64_runtime_${name}_${os.getpid()}')
420 os.mkdir_all(tmp_dir) or { panic(err) }
421 source_path := os.join_path(tmp_dir, '${name}.v')
422 bin_path := x64_host_bin_path(tmp_dir, name)
423 os.write_file(source_path, source) or { panic(err) }
424 vexe := os.getenv_opt('VEXE') or { @VEXE }
425 mut build := os.new_process(vexe)
426 defer {
427 build.close()
428 }
429 build.set_environment(x64_pinned_v2_build_environment(vexe, tmp_dir))
430 build.set_args(['-v2', '-no-parallel', '-b', 'x64', source_path, '-o', bin_path])
431 build.set_redirect_stdio()
432 build.run()
433 build.wait()
434 build_output := 'stdout:\n${build.stdout_slurp()}\nstderr:\n${build.stderr_slurp()}'
435 if build.code != 0 {
436 assert false, x64_host_build_failure_message(name, tmp_dir, source_path, source, bin_path,
437 build.code, build_output)
438 }
439 mut run := os.new_process(bin_path)
440 defer {
441 run.close()
442 }
443 run.set_redirect_stdio()
444 run.run()
445 run.wait()
446 stdout := run.stdout_slurp().bytes()
447 stderr := run.stderr_slurp().bytes()
448 if run.code != 0 {
449 assert false, x64_host_run_failure_message(name, tmp_dir, source_path, source, bin_path,
450 build_output, run.code, stdout, stderr)
451 }
452 return X64HostRunResult{
453 name: name
454 tmp_dir: tmp_dir
455 source_path: source_path
456 source_text: source
457 bin_path: bin_path
458 build_output: build_output
459 stdout: stdout
460 stderr: stderr
461 }
462}
463
464fn run_x64_host_program_redirected_auto_with_args(name string, source string, args []string) X64HostRunResult {
465 tmp_dir := os.join_path(os.vtmp_dir(), 'v2_x64_runtime_${name}_${os.getpid()}')
466 os.mkdir_all(tmp_dir) or { panic(err) }
467 source_path := os.join_path(tmp_dir, '${name}.v')
468 bin_path := x64_host_bin_path(tmp_dir, name)
469 os.write_file(source_path, source) or { panic(err) }
470 vexe := os.getenv_opt('VEXE') or { @VEXE }
471 mut build := os.new_process(vexe)
472 defer {
473 build.close()
474 }
475 build.set_environment(x64_pinned_v2_build_environment(vexe, tmp_dir))
476 build.set_args(['-v2', '-no-parallel', '-b', 'x64', source_path, '-o', bin_path])
477 build.set_redirect_stdio()
478 build.run()
479 build.wait()
480 build_output := 'stdout:\n${build.stdout_slurp()}\nstderr:\n${build.stderr_slurp()}'
481 if build.code != 0 {
482 assert false, x64_host_build_failure_message(name, tmp_dir, source_path, source, bin_path,
483 build.code, build_output)
484 }
485 mut run := os.new_process(bin_path)
486 defer {
487 run.close()
488 }
489 run.set_args(args)
490 run.set_redirect_stdio()
491 run.run()
492 run.wait()
493 stdout := run.stdout_slurp().bytes()
494 stderr := run.stderr_slurp().bytes()
495 if run.code != 0 {
496 assert false, x64_host_run_failure_message(name, tmp_dir, source_path, source, bin_path,
497 build_output, run.code, stdout, stderr)
498 }
499 return X64HostRunResult{
500 name: name
501 tmp_dir: tmp_dir
502 source_path: source_path
503 source_text: source
504 bin_path: bin_path
505 build_output: build_output
506 stdout: stdout
507 stderr: stderr
508 }
509}
510
511fn run_x64_host_program_redirected_macos_auto_tiny_verbose_with_args(name string, source string, args []string) X64HostRunResult {
512 tmp_dir := os.join_path(os.vtmp_dir(), 'v2_x64_runtime_${name}_${os.getpid()}')
513 os.mkdir_all(tmp_dir) or { panic(err) }
514 source_path := os.join_path(tmp_dir, '${name}.v')
515 bin_path := x64_host_bin_path(tmp_dir, name)
516 os.write_file(source_path, source) or { panic(err) }
517 vexe := os.getenv_opt('VEXE') or { @VEXE }
518 mut build := os.new_process(vexe)
519 defer {
520 build.close()
521 }
522 build.set_environment(x64_macos_auto_tiny_build_environment(vexe, tmp_dir))
523 build.set_args(['-v2', '-v', '-no-parallel', '-b', 'x64', source_path, '-o', bin_path])
524 build.set_redirect_stdio()
525 build.run()
526 build.wait()
527 build_output := 'stdout:\n${build.stdout_slurp()}\nstderr:\n${build.stderr_slurp()}'
528 if build.code != 0 {
529 assert false, x64_host_build_failure_message(name, tmp_dir, source_path, source, bin_path,
530 build.code, build_output)
531 }
532 mut run := os.new_process(bin_path)
533 defer {
534 run.close()
535 }
536 run.set_args(args)
537 run.set_redirect_stdio()
538 run.run()
539 run.wait()
540 stdout := run.stdout_slurp().bytes()
541 stderr := run.stderr_slurp().bytes()
542 if run.code != 0 {
543 assert false, x64_host_run_failure_message(name, tmp_dir, source_path, source, bin_path,
544 build_output, run.code, stdout, stderr)
545 }
546 return X64HostRunResult{
547 name: name
548 tmp_dir: tmp_dir
549 source_path: source_path
550 source_text: source
551 bin_path: bin_path
552 build_output: build_output
553 stdout: stdout
554 stderr: stderr
555 }
556}
557
558fn run_x64_host_program_redirected_with_exit(name string, source string) X64HostRunExitResult {
559 tmp_dir := os.join_path(os.vtmp_dir(), 'v2_x64_runtime_${name}_${os.getpid()}')
560 os.mkdir_all(tmp_dir) or { panic(err) }
561 source_path := os.join_path(tmp_dir, '${name}.v')
562 bin_path := x64_host_bin_path(tmp_dir, name)
563 os.write_file(source_path, source) or { panic(err) }
564 vexe := os.getenv_opt('VEXE') or { @VEXE }
565 build :=
566 os.execute('${os.quoted_path(vexe)} -v2 -no-parallel -b x64 ${os.quoted_path(source_path)} -o ${os.quoted_path(bin_path)}')
567 if build.exit_code != 0 {
568 assert false, x64_host_build_failure_message(name, tmp_dir, source_path, source, bin_path,
569 build.exit_code, build.output)
570 }
571 mut run := os.new_process(bin_path)
572 defer {
573 run.close()
574 }
575 run.set_redirect_stdio()
576 run.run()
577 run.wait()
578 stdout := run.stdout_slurp().bytes()
579 stderr := run.stderr_slurp().bytes()
580 return X64HostRunExitResult{
581 name: name
582 tmp_dir: tmp_dir
583 source_path: source_path
584 source_text: source
585 bin_path: bin_path
586 build_output: build.output
587 stdout: stdout
588 stderr: stderr
589 exit_code: run.code
590 }
591}
592
593fn x64_write_project_sources(root string, sources map[string]string) string {
594 mut source_text := ''
595 mut rel_paths := sources.keys()
596 rel_paths.sort()
597 for rel_path in rel_paths {
598 source := sources[rel_path]
599 source_path := os.join_path(root, rel_path)
600 os.mkdir_all(os.dir(source_path)) or { panic(err) }
601 os.write_file(source_path, source) or { panic(err) }
602 source_text += '--- ${rel_path} ---\n${source}\n'
603 }
604 return source_text
605}
606
607fn run_x64_host_project_redirected(name string, sources map[string]string) X64HostRunResult {
608 tmp_dir := os.join_path(os.vtmp_dir(), 'v2_x64_runtime_${name}_${os.getpid()}')
609 os.mkdir_all(tmp_dir) or { panic(err) }
610 bin_path := x64_host_bin_path(tmp_dir, name)
611 source_root := tmp_dir
612 mut source_text := ''
613 for rel_path, source in sources {
614 source_path := os.join_path(tmp_dir, rel_path)
615 os.mkdir_all(os.dir(source_path)) or { panic(err) }
616 os.write_file(source_path, source) or { panic(err) }
617 source_text += '--- ${rel_path} ---\n${source}\n'
618 }
619 vexe := os.getenv_opt('VEXE') or { @VEXE }
620 build :=
621 os.execute('${os.quoted_path(vexe)} -v2 -no-parallel -b x64 ${os.quoted_path(tmp_dir)} -o ${os.quoted_path(bin_path)}')
622 if build.exit_code != 0 {
623 assert false, x64_host_build_failure_message(name, tmp_dir, source_root, source_text,
624 bin_path, build.exit_code, build.output)
625 }
626 mut run := os.new_process(bin_path)
627 defer {
628 run.close()
629 }
630 run.set_redirect_stdio()
631 run.run()
632 run.wait()
633 stdout := run.stdout_slurp().bytes()
634 stderr := run.stderr_slurp().bytes()
635 if run.code != 0 {
636 assert false, x64_host_run_failure_message(name, tmp_dir, source_root, source_text,
637 bin_path, build.output, run.code, stdout, stderr)
638 }
639 return X64HostRunResult{
640 name: name
641 tmp_dir: tmp_dir
642 source_path: source_root
643 source_text: source_text
644 bin_path: bin_path
645 build_output: build.output
646 stdout: stdout
647 stderr: stderr
648 }
649}
650
651fn run_x64_host_project_redirected_auto(name string, sources map[string]string) X64HostRunResult {
652 tmp_dir := os.join_path(os.vtmp_dir(), 'v2_x64_runtime_${name}_${os.getpid()}')
653 os.mkdir_all(tmp_dir) or { panic(err) }
654 bin_path := x64_host_bin_path(tmp_dir, name)
655 source_root := tmp_dir
656 source_text := x64_write_project_sources(tmp_dir, sources)
657 vexe := x64_vexe_command_path()
658 mut build := os.new_process(vexe)
659 defer {
660 build.close()
661 }
662 build.set_environment(x64_pinned_v2_build_environment(vexe, tmp_dir))
663 build.set_args(['-v2', '-no-parallel', '-b', 'x64', tmp_dir, '-o', bin_path])
664 build.set_redirect_stdio()
665 build.run()
666 build.wait()
667 build_output := 'stdout:\n${build.stdout_slurp()}\nstderr:\n${build.stderr_slurp()}'
668 if build.code != 0 {
669 assert false, x64_host_build_failure_message(name, tmp_dir, source_root, source_text,
670 bin_path, build.code, build_output)
671 }
672 mut run := os.new_process(bin_path)
673 defer {
674 run.close()
675 }
676 run.set_redirect_stdio()
677 run.run()
678 run.wait()
679 stdout := run.stdout_slurp().bytes()
680 stderr := run.stderr_slurp().bytes()
681 if run.code != 0 {
682 assert false, x64_host_run_failure_message(name, tmp_dir, source_root, source_text,
683 bin_path, build_output, run.code, stdout, stderr)
684 }
685 return X64HostRunResult{
686 name: name
687 tmp_dir: tmp_dir
688 source_path: source_root
689 source_text: source_text
690 bin_path: bin_path
691 build_output: build_output
692 stdout: stdout
693 stderr: stderr
694 }
695}
696
697fn run_x64_host_project_redirected_macos_auto_tiny_verbose(name string, sources map[string]string) X64HostRunResult {
698 tmp_dir := os.join_path(os.vtmp_dir(), 'v2_x64_runtime_${name}_${os.getpid()}')
699 os.mkdir_all(tmp_dir) or { panic(err) }
700 bin_path := x64_host_bin_path(tmp_dir, name)
701 source_root := tmp_dir
702 source_text := x64_write_project_sources(tmp_dir, sources)
703 vexe := x64_vexe_command_path()
704 mut build := os.new_process(vexe)
705 defer {
706 build.close()
707 }
708 build.set_environment(x64_macos_auto_tiny_build_environment(vexe, tmp_dir))
709 build.set_args(['-v2', '-v', '-no-parallel', '-b', 'x64', tmp_dir, '-o', bin_path])
710 build.set_redirect_stdio()
711 build.run()
712 build.wait()
713 build_output := 'stdout:\n${build.stdout_slurp()}\nstderr:\n${build.stderr_slurp()}'
714 if build.code != 0 {
715 assert false, x64_host_build_failure_message(name, tmp_dir, source_root, source_text,
716 bin_path, build.code, build_output)
717 }
718 mut run := os.new_process(bin_path)
719 defer {
720 run.close()
721 }
722 run.set_redirect_stdio()
723 run.run()
724 run.wait()
725 stdout := run.stdout_slurp().bytes()
726 stderr := run.stderr_slurp().bytes()
727 if run.code != 0 {
728 assert false, x64_host_run_failure_message(name, tmp_dir, source_root, source_text,
729 bin_path, build_output, run.code, stdout, stderr)
730 }
731 return X64HostRunResult{
732 name: name
733 tmp_dir: tmp_dir
734 source_path: source_root
735 source_text: source_text
736 bin_path: bin_path
737 build_output: build_output
738 stdout: stdout
739 stderr: stderr
740 }
741}
742
743fn run_x64_host_file_redirected(name string, source_dir string, source_file string) X64HostRunResult {
744 tmp_dir := os.join_path(os.vtmp_dir(), 'v2_x64_runtime_${name}_${os.getpid()}')
745 os.mkdir_all(tmp_dir) or { panic(err) }
746 source_path := os.join_path(source_dir, source_file)
747 source_text := 'source file: ${source_path}'
748 bin_path := x64_host_bin_path(tmp_dir, name)
749 vexe := x64_vexe_command_path()
750 build := x64_build_file_from_dir(vexe, source_dir, source_file, bin_path)
751 if build.exit_code != 0 {
752 assert false, x64_host_build_failure_message(name, tmp_dir, source_path, source_text,
753 bin_path, build.exit_code, build.output)
754 }
755 mut run := os.new_process(bin_path)
756 defer {
757 run.close()
758 }
759 run.set_redirect_stdio()
760 run.run()
761 run.wait()
762 stdout := run.stdout_slurp().bytes()
763 stderr := run.stderr_slurp().bytes()
764 if run.code != 0 {
765 assert false, x64_host_run_failure_message(name, tmp_dir, source_path, source_text,
766 bin_path, build.output, run.code, stdout, stderr)
767 }
768 return X64HostRunResult{
769 name: name
770 tmp_dir: tmp_dir
771 source_path: source_path
772 source_text: source_text
773 bin_path: bin_path
774 build_output: build.output
775 stdout: stdout
776 stderr: stderr
777 }
778}
779
780fn run_x64_host_file_redirected_tiny(name string, source_dir string, source_file string) X64HostRunResult {
781 tmp_dir := os.join_path(os.vtmp_dir(), 'v2_x64_runtime_${name}_${os.getpid()}')
782 os.mkdir_all(tmp_dir) or { panic(err) }
783 source_path := os.join_path(source_dir, source_file)
784 source_text := 'source file: ${source_path}'
785 bin_path := x64_host_bin_path(tmp_dir, name)
786 vexe := x64_vexe_command_path()
787 mut build := os.new_process(vexe)
788 defer {
789 build.close()
790 }
791 build.set_environment(x64_strict_tiny_build_environment(vexe, tmp_dir))
792 build.set_work_folder(source_dir)
793 build.set_args(['-v2', '-no-parallel', '-b', 'x64', source_file, '-o', bin_path])
794 build.set_redirect_stdio()
795 build.run()
796 build.wait()
797 build_output := 'stdout:\n${build.stdout_slurp()}\nstderr:\n${build.stderr_slurp()}'
798 if build.code != 0 {
799 assert false, x64_host_build_failure_message(name, tmp_dir, source_path, source_text,
800 bin_path, build.code, build_output)
801 }
802 mut run := os.new_process(bin_path)
803 defer {
804 run.close()
805 }
806 run.set_redirect_stdio()
807 run.run()
808 run.wait()
809 stdout := run.stdout_slurp().bytes()
810 stderr := run.stderr_slurp().bytes()
811 if run.code != 0 {
812 assert false, x64_host_run_failure_message(name, tmp_dir, source_path, source_text,
813 bin_path, build_output, run.code, stdout, stderr)
814 }
815 return X64HostRunResult{
816 name: name
817 tmp_dir: tmp_dir
818 source_path: source_path
819 source_text: source_text
820 bin_path: bin_path
821 build_output: build_output
822 stdout: stdout
823 stderr: stderr
824 }
825}
826
827fn assert_x64_linux_tiny_file_build_rejected(name string, source_dir string, source_file string, expected_message string) {
828 $if linux {
829 tmp_dir := os.join_path(os.vtmp_dir(), 'v2_x64_runtime_${name}_${os.getpid()}')
830 os.mkdir_all(tmp_dir) or { panic(err) }
831 defer {
832 os.rmdir_all(tmp_dir) or {}
833 }
834 source_path := os.join_path(source_dir, source_file)
835 source_text := 'source file: ${source_path}'
836 bin_path := x64_host_bin_path(tmp_dir, name)
837 vexe := x64_vexe_command_path()
838 mut build := os.new_process(vexe)
839 defer {
840 build.close()
841 }
842 build.set_environment(x64_strict_tiny_build_environment(vexe, tmp_dir))
843 build.set_work_folder(source_dir)
844 build.set_args(['-v2', '-no-parallel', '-b', 'x64', source_file, '-o', bin_path])
845 build.set_redirect_stdio()
846 build.run()
847 build.wait()
848 build_output := 'stdout:\n${build.stdout_slurp()}\nstderr:\n${build.stderr_slurp()}'
849 assert build.code != 0, '${name} unexpectedly built with Linux tiny:\n${build_output}'
850 assert build_output.contains(linux_tiny_not_eligible_prefix), '${x64_host_build_failure_message(name,
851 tmp_dir, source_path, source_text, bin_path, build.code, build_output)}\nexpected Linux tiny rejection prefix `${linux_tiny_not_eligible_prefix}`'
852
853 assert build_output.contains(expected_message), '${x64_host_build_failure_message(name,
854 tmp_dir, source_path, source_text, bin_path, build.code, build_output)}\nexpected rejection to contain `${expected_message}`'
855
856 assert !os.exists(bin_path), '${name} produced a binary despite Linux tiny rejection: ${bin_path}'
857 }
858}
859
860fn run_x64_host_file_redirected_auto(name string, source_dir string, source_file string) X64HostRunResult {
861 tmp_dir := os.join_path(os.vtmp_dir(), 'v2_x64_runtime_${name}_${os.getpid()}')
862 os.mkdir_all(tmp_dir) or { panic(err) }
863 source_path := os.join_path(source_dir, source_file)
864 source_text := 'source file: ${source_path}'
865 bin_path := x64_host_bin_path(tmp_dir, name)
866 vexe := x64_vexe_command_path()
867 mut build := os.new_process(vexe)
868 defer {
869 build.close()
870 }
871 build.set_environment(x64_pinned_v2_build_environment(vexe, tmp_dir))
872 build.set_work_folder(source_dir)
873 build.set_args(['-v2', '-no-parallel', '-b', 'x64', source_file, '-o', bin_path])
874 build.set_redirect_stdio()
875 build.run()
876 build.wait()
877 build_output := 'stdout:\n${build.stdout_slurp()}\nstderr:\n${build.stderr_slurp()}'
878 if build.code != 0 {
879 assert false, x64_host_build_failure_message(name, tmp_dir, source_path, source_text,
880 bin_path, build.code, build_output)
881 }
882 mut run := os.new_process(bin_path)
883 defer {
884 run.close()
885 }
886 run.set_redirect_stdio()
887 run.run()
888 run.wait()
889 stdout := run.stdout_slurp().bytes()
890 stderr := run.stderr_slurp().bytes()
891 if run.code != 0 {
892 assert false, x64_host_run_failure_message(name, tmp_dir, source_path, source_text,
893 bin_path, build_output, run.code, stdout, stderr)
894 }
895 return X64HostRunResult{
896 name: name
897 tmp_dir: tmp_dir
898 source_path: source_path
899 source_text: source_text
900 bin_path: bin_path
901 build_output: build_output
902 stdout: stdout
903 stderr: stderr
904 }
905}
906
907fn run_x64_host_file_redirected_auto_with_args(name string, source_dir string, source_file string, args []string) X64HostRunResult {
908 tmp_dir := os.join_path(os.vtmp_dir(), 'v2_x64_runtime_${name}_${os.getpid()}')
909 os.mkdir_all(tmp_dir) or { panic(err) }
910 source_path := os.join_path(source_dir, source_file)
911 source_text := 'source file: ${source_path}'
912 bin_path := x64_host_bin_path(tmp_dir, name)
913 vexe := x64_vexe_command_path()
914 mut build := os.new_process(vexe)
915 defer {
916 build.close()
917 }
918 build.set_environment(x64_pinned_v2_build_environment(vexe, tmp_dir))
919 build.set_work_folder(source_dir)
920 build.set_args(['-v2', '-no-parallel', '-b', 'x64', source_file, '-o', bin_path])
921 build.set_redirect_stdio()
922 build.run()
923 build.wait()
924 build_output := 'stdout:\n${build.stdout_slurp()}\nstderr:\n${build.stderr_slurp()}'
925 if build.code != 0 {
926 assert false, x64_host_build_failure_message(name, tmp_dir, source_path, source_text,
927 bin_path, build.code, build_output)
928 }
929 mut run := os.new_process(bin_path)
930 defer {
931 run.close()
932 }
933 run.set_args(args)
934 run.set_redirect_stdio()
935 run.run()
936 run.wait()
937 stdout := run.stdout_slurp().bytes()
938 stderr := run.stderr_slurp().bytes()
939 if run.code != 0 {
940 assert false, x64_host_run_failure_message(name, tmp_dir, source_path, source_text,
941 bin_path, build_output, run.code, stdout, stderr)
942 }
943 return X64HostRunResult{
944 name: name
945 tmp_dir: tmp_dir
946 source_path: source_path
947 source_text: source_text
948 bin_path: bin_path
949 build_output: build_output
950 stdout: stdout
951 stderr: stderr
952 }
953}
954
955fn x64_shell_redirect_args(args []string) string {
956 mut quoted := []string{cap: args.len}
957 for arg in args {
958 quoted << os.quoted_path(arg)
959 }
960 return quoted.join(' ')
961}
962
963fn run_x64_host_file_redirected_auto_with_stdin_and_args(name string, source_dir string, source_file string, stdin_text string, args []string) X64HostRunResult {
964 tmp_dir := os.join_path(os.vtmp_dir(), 'v2_x64_runtime_${name}_${os.getpid()}')
965 os.mkdir_all(tmp_dir) or { panic(err) }
966 source_path := os.join_path(source_dir, source_file)
967 source_text := 'source file: ${source_path}\nstdin text:\n${stdin_text}'
968 bin_path := x64_host_bin_path(tmp_dir, name)
969 stdin_path := os.join_path(tmp_dir, '${name}.in')
970 stdout_path := os.join_path(tmp_dir, '${name}.out')
971 stderr_path := os.join_path(tmp_dir, '${name}.err')
972 os.write_file(stdin_path, stdin_text) or { panic(err) }
973 vexe := x64_vexe_command_path()
974 build := x64_build_file_from_dir(vexe, source_dir, source_file, bin_path)
975 build_output := build.output
976 if build.exit_code != 0 {
977 assert false, x64_host_build_failure_message(name, tmp_dir, source_path, source_text,
978 bin_path, build.exit_code, build.output)
979 }
980 arg_text := x64_shell_redirect_args(args)
981 mut command := os.quoted_path(bin_path)
982 if arg_text != '' {
983 command += ' ${arg_text}'
984 }
985 command += ' < ${os.quoted_path(stdin_path)} > ${os.quoted_path(stdout_path)} 2> ${os.quoted_path(stderr_path)}'
986 run := os.execute(command)
987 stdout := os.read_bytes(stdout_path) or { panic(err) }
988 stderr := os.read_bytes(stderr_path) or { panic(err) }
989 if run.exit_code != 0 {
990 assert false, x64_host_run_failure_message(name, tmp_dir, source_path, source_text,
991 bin_path, build_output, run.exit_code, stdout, stderr)
992 }
993 return X64HostRunResult{
994 name: name
995 tmp_dir: tmp_dir
996 source_path: source_path
997 source_text: source_text
998 bin_path: bin_path
999 build_output: build_output
1000 stdout: stdout
1001 stderr: stderr
1002 }
1003}
1004
1005fn run_x64_host_file_redirected_macos_auto_tiny_verbose_with_args(name string, source_dir string, source_file string, args []string) X64HostRunResult {
1006 tmp_dir := os.join_path(os.vtmp_dir(), 'v2_x64_runtime_${name}_${os.getpid()}')
1007 os.mkdir_all(tmp_dir) or { panic(err) }
1008 source_path := os.join_path(source_dir, source_file)
1009 source_text := 'source file: ${source_path}'
1010 bin_path := x64_host_bin_path(tmp_dir, name)
1011 vexe := x64_vexe_command_path()
1012 mut build := os.new_process(vexe)
1013 defer {
1014 build.close()
1015 }
1016 build.set_environment(x64_macos_auto_tiny_build_environment(vexe, tmp_dir))
1017 build.set_work_folder(source_dir)
1018 build.set_args(['-v2', '-v', '-no-parallel', '-b', 'x64', source_file, '-o', bin_path])
1019 build.set_redirect_stdio()
1020 build.run()
1021 build.wait()
1022 build_output := 'stdout:\n${build.stdout_slurp()}\nstderr:\n${build.stderr_slurp()}'
1023 if build.code != 0 {
1024 assert false, x64_host_build_failure_message(name, tmp_dir, source_path, source_text,
1025 bin_path, build.code, build_output)
1026 }
1027 mut run := os.new_process(bin_path)
1028 defer {
1029 run.close()
1030 }
1031 run.set_args(args)
1032 run.set_redirect_stdio()
1033 run.run()
1034 run.wait()
1035 stdout := run.stdout_slurp().bytes()
1036 stderr := run.stderr_slurp().bytes()
1037 if run.code != 0 {
1038 assert false, x64_host_run_failure_message(name, tmp_dir, source_path, source_text,
1039 bin_path, build_output, run.code, stdout, stderr)
1040 }
1041 return X64HostRunResult{
1042 name: name
1043 tmp_dir: tmp_dir
1044 source_path: source_path
1045 source_text: source_text
1046 bin_path: bin_path
1047 build_output: build_output
1048 stdout: stdout
1049 stderr: stderr
1050 }
1051}
1052
1053fn run_x64_host_file_redirected_macos_auto_tiny(name string, source_dir string, source_file string) X64HostRunResult {
1054 tmp_dir := os.join_path(os.vtmp_dir(), 'v2_x64_runtime_${name}_${os.getpid()}')
1055 os.mkdir_all(tmp_dir) or { panic(err) }
1056 source_path := os.join_path(source_dir, source_file)
1057 source_text := 'source file: ${source_path}'
1058 bin_path := x64_host_bin_path(tmp_dir, name)
1059 vexe := x64_vexe_command_path()
1060 mut build := os.new_process(vexe)
1061 defer {
1062 build.close()
1063 }
1064 build.set_environment(x64_macos_auto_tiny_build_environment(vexe, tmp_dir))
1065 build.set_work_folder(source_dir)
1066 build.set_args(['-v2', '-v', '-no-parallel', '-b', 'x64', source_file, '-o', bin_path])
1067 build.set_redirect_stdio()
1068 build.run()
1069 build.wait()
1070 build_output := 'stdout:\n${build.stdout_slurp()}\nstderr:\n${build.stderr_slurp()}'
1071 if build.code != 0 {
1072 assert false, x64_host_build_failure_message(name, tmp_dir, source_path, source_text,
1073 bin_path, build.code, build_output)
1074 }
1075 mut run := os.new_process(bin_path)
1076 defer {
1077 run.close()
1078 }
1079 run.set_redirect_stdio()
1080 run.run()
1081 run.wait()
1082 stdout := run.stdout_slurp().bytes()
1083 stderr := run.stderr_slurp().bytes()
1084 if run.code != 0 {
1085 assert false, x64_host_run_failure_message(name, tmp_dir, source_path, source_text,
1086 bin_path, build_output, run.code, stdout, stderr)
1087 }
1088 return X64HostRunResult{
1089 name: name
1090 tmp_dir: tmp_dir
1091 source_path: source_path
1092 source_text: source_text
1093 bin_path: bin_path
1094 build_output: build_output
1095 stdout: stdout
1096 stderr: stderr
1097 }
1098}
1099
1100fn run_x64_host_file_redirected_no_tiny(name string, source_dir string, source_file string) X64HostRunResult {
1101 tmp_dir := os.join_path(os.vtmp_dir(), 'v2_x64_runtime_${name}_${os.getpid()}')
1102 os.mkdir_all(tmp_dir) or { panic(err) }
1103 source_path := os.join_path(source_dir, source_file)
1104 source_text := 'source file: ${source_path}'
1105 bin_path := x64_host_bin_path(tmp_dir, name)
1106 vexe := x64_vexe_command_path()
1107 mut build := os.new_process(vexe)
1108 defer {
1109 build.close()
1110 }
1111 build.set_environment(x64_no_tiny_build_environment(vexe, tmp_dir))
1112 build.set_work_folder(source_dir)
1113 build.set_args(['-v2', '-no-parallel', '-b', 'x64', '-no-mos-tiny', source_file, '-o', bin_path])
1114 build.set_redirect_stdio()
1115 build.run()
1116 build.wait()
1117 build_output := 'stdout:\n${build.stdout_slurp()}\nstderr:\n${build.stderr_slurp()}'
1118 if build.code != 0 {
1119 assert false, x64_host_build_failure_message(name, tmp_dir, source_path, source_text,
1120 bin_path, build.code, build_output)
1121 }
1122 mut run := os.new_process(bin_path)
1123 defer {
1124 run.close()
1125 }
1126 run.set_redirect_stdio()
1127 run.run()
1128 run.wait()
1129 stdout := run.stdout_slurp().bytes()
1130 stderr := run.stderr_slurp().bytes()
1131 if run.code != 0 {
1132 assert false, x64_host_run_failure_message(name, tmp_dir, source_path, source_text,
1133 bin_path, build_output, run.code, stdout, stderr)
1134 }
1135 return X64HostRunResult{
1136 name: name
1137 tmp_dir: tmp_dir
1138 source_path: source_path
1139 source_text: source_text
1140 bin_path: bin_path
1141 build_output: build_output
1142 stdout: stdout
1143 stderr: stderr
1144 }
1145}
1146
1147fn assert_x64_linux_stdout_bytes(name string, source string, expected_stdout []u8) {
1148 $if linux {
1149 result := run_x64_linux_program_redirected(name, source)
1150 assert result.stdout == expected_stdout, '${name} stdout mismatch: ${result.stdout}'
1151 assert result.stderr == []u8{}, '${name} stderr mismatch: ${result.stderr}'
1152 }
1153}
1154
1155fn assert_x64_linux_file_stdout_bytes(name string, source_dir string, source_file string, expected_stdout []u8) {
1156 $if linux {
1157 result := run_x64_linux_file_redirected(name, source_dir, source_file)
1158 assert result.stdout == expected_stdout, '${name} stdout mismatch: ${result.stdout}'
1159 assert result.stderr == []u8{}, '${name} stderr mismatch: ${result.stderr}'
1160 }
1161}
1162
1163fn x64_v_run_file_stdout_bytes(source_dir string, source_file string) []u8 {
1164 return x64_v_run_file_stdout_bytes_with_args(source_dir, source_file, []string{})
1165}
1166
1167fn x64_v_run_file_stdout_bytes_with_args(source_dir string, source_file string, args []string) []u8 {
1168 vexe := x64_vexe_command_path()
1169 source_path := os.join_path(source_dir, source_file)
1170 mut run := os.new_process(vexe)
1171 defer {
1172 run.close()
1173 }
1174 mut run_args := ['run', source_file]
1175 for arg in args {
1176 run_args << arg
1177 }
1178 run.set_work_folder(source_dir)
1179 run.set_args(run_args)
1180 run.set_redirect_stdio()
1181 run.run()
1182 run.wait()
1183 stdout := run.stdout_slurp().bytes()
1184 stderr := run.stderr_slurp()
1185 assert run.code == 0, 'v run ${source_path} failed with code ${run.code}\nstdout:\n${stdout.bytestr()}\nstderr:\n${stderr}'
1186 assert x64_v_run_oracle_stderr_is_allowed(stderr), 'v run ${source_path} wrote unexpected stderr:\n${stderr}'
1187 return stdout
1188}
1189
1190fn x64_v_run_oracle_stderr_is_allowed(stderr string) bool {
1191 if stderr == '' {
1192 return true
1193 }
1194 clean := x64_strip_ansi_csi(stderr).trim_space()
1195 return clean == 'warning: tcc compilation failed, falling back to cc (this is much slower)'
1196}
1197
1198fn x64_strip_ansi_csi(text string) string {
1199 bytes := text.bytes()
1200 mut out := []u8{cap: bytes.len}
1201 mut i := 0
1202 for i < bytes.len {
1203 if bytes[i] == 0x1b && i + 1 < bytes.len && bytes[i + 1] == `[` {
1204 i += 2
1205 for i < bytes.len {
1206 b := bytes[i]
1207 i++
1208 if b >= 0x40 && b <= 0x7e {
1209 break
1210 }
1211 }
1212 continue
1213 }
1214 out << bytes[i]
1215 i++
1216 }
1217 return out.bytestr()
1218}
1219
1220fn assert_x64_linux_file_stdout_matches_v_run(name string, source_dir string, source_file string) {
1221 $if linux {
1222 expected_stdout := x64_v_run_file_stdout_bytes(source_dir, source_file)
1223 assert_x64_linux_file_stdout_bytes(name, source_dir, source_file, expected_stdout)
1224 }
1225}
1226
1227fn assert_x64_linux_file_stdout_matches_v_run_with_args(name string, source_dir string, source_file string, args []string) {
1228 $if linux {
1229 expected_stdout := x64_v_run_file_stdout_bytes_with_args(source_dir, source_file, args)
1230 result := run_x64_host_file_redirected_auto_with_args(name, source_dir, source_file, args)
1231 assert_x64_linux_hosted_libc_binary(result, expected_stdout)
1232 x64_host_cleanup_tmp(result.tmp_dir)
1233 }
1234}
1235
1236fn assert_x64_linux_file_stdout_bytes_with_stdin(name string, source_dir string, source_file string, stdin_text string, expected_stdout []u8) {
1237 $if linux {
1238 result := run_x64_host_file_redirected_auto_with_stdin_and_args(name, source_dir,
1239 source_file, stdin_text, []string{})
1240 assert_x64_linux_hosted_libc_binary(result, expected_stdout)
1241 x64_host_cleanup_tmp(result.tmp_dir)
1242 }
1243}
1244
1245fn assert_x64_macos_windows_file_stdout_matches_v_run(name string, source_dir string, source_file string) {
1246 $if macos {
1247 expected_stdout := x64_v_run_file_stdout_bytes(source_dir, source_file)
1248 assert_x64_macos_windows_file_stdout_bytes(name, source_dir, source_file, expected_stdout)
1249 }
1250 $if windows {
1251 expected_stdout := x64_v_run_file_stdout_bytes(source_dir, source_file)
1252 assert_x64_macos_windows_file_stdout_bytes(name, source_dir, source_file, expected_stdout)
1253 }
1254}
1255
1256fn assert_x64_macos_windows_file_stdout_matches_v_run_with_args(name string, source_dir string, source_file string, args []string) {
1257 $if macos {
1258 expected_stdout := x64_v_run_file_stdout_bytes_with_args(source_dir, source_file, args)
1259 result := run_x64_host_file_redirected_macos_auto_tiny_verbose_with_args('macos_${name}',
1260 source_dir, source_file, args)
1261 context := x64_host_result_context(result)
1262 stdout_message := x64_stdout_mismatch_message(name, 'macos', expected_stdout,
1263 result.stdout, context)
1264 stderr_message := x64_stderr_mismatch_message(name, 'macos', []u8{}, result.stderr, context)
1265 assert result.stdout == expected_stdout, stdout_message
1266 assert result.stderr == []u8{}, stderr_message
1267 x64_host_cleanup_tmp(result.tmp_dir)
1268 }
1269 $if windows {
1270 expected_stdout := x64_v_run_file_stdout_bytes_with_args(source_dir, source_file, args)
1271 result := run_x64_host_file_redirected_auto_with_args('windows_${name}', source_dir,
1272 source_file, args)
1273 context := x64_host_result_context(result)
1274 stdout_message := x64_stdout_mismatch_message(name, 'windows', expected_stdout,
1275 result.stdout, context)
1276 stderr_message := x64_stderr_mismatch_message(name, 'windows', []u8{}, result.stderr,
1277 context)
1278 assert result.stdout == expected_stdout, stdout_message
1279 assert result.stderr == []u8{}, stderr_message
1280 x64_host_cleanup_tmp(result.tmp_dir)
1281 }
1282}
1283
1284fn assert_x64_macos_windows_file_stdout_bytes_with_stdin(name string, source_dir string, source_file string, stdin_text string, expected_stdout []u8) {
1285 $if macos {
1286 result := run_x64_host_file_redirected_auto_with_stdin_and_args('macos_${name}',
1287 source_dir, source_file, stdin_text, []string{})
1288 context := x64_host_result_context(result)
1289 stdout_message := x64_stdout_mismatch_message(name, 'macos', expected_stdout,
1290 result.stdout, context)
1291 stderr_message := x64_stderr_mismatch_message(name, 'macos', []u8{}, result.stderr, context)
1292 assert result.stdout == expected_stdout, stdout_message
1293 assert result.stderr == []u8{}, stderr_message
1294 x64_host_cleanup_tmp(result.tmp_dir)
1295 }
1296 $if windows {
1297 result := run_x64_host_file_redirected_auto_with_stdin_and_args('windows_${name}',
1298 source_dir, source_file, stdin_text, []string{})
1299 context := x64_host_result_context(result)
1300 stdout_message := x64_stdout_mismatch_message(name, 'windows', expected_stdout,
1301 result.stdout, context)
1302 stderr_message := x64_stderr_mismatch_message(name, 'windows', []u8{}, result.stderr,
1303 context)
1304 assert result.stdout == expected_stdout, stdout_message
1305 assert result.stderr == []u8{}, stderr_message
1306 x64_host_cleanup_tmp(result.tmp_dir)
1307 }
1308}
1309
1310fn assert_x64_linux_no_libc_binary(result X64HostRunResult, expected_stdout []u8) {
1311 $if linux {
1312 context := x64_host_result_context(result)
1313 assert result.stdout == expected_stdout, x64_stdout_mismatch_message(result.name, 'linux',
1314 expected_stdout, result.stdout, context)
1315
1316 assert result.stderr == []u8{}, x64_stderr_mismatch_message(result.name, 'linux', []u8{},
1317 result.stderr, context)
1318
1319 assert os.file_size(result.bin_path) < 16 * 1024, '${context}\nbinary is not tiny: ${os.file_size(result.bin_path)} bytes'
1320 if readelf_dynamic := x64_optional_tool_output(@FN, 'readelf',
1321 '-d ${os.quoted_path(result.bin_path)}')
1322 {
1323 assert readelf_dynamic.contains('There is no dynamic section in this file.'), '${context}\nreadelf -d output:\n${readelf_dynamic}'
1324 }
1325
1326 if readelf_headers := x64_optional_tool_output(@FN, 'readelf',
1327 '-h -l ${os.quoted_path(result.bin_path)}')
1328 {
1329 assert readelf_headers.contains('Type: EXEC (Executable file)'), readelf_headers
1330
1331 assert readelf_headers.contains('LOAD'), readelf_headers
1332 }
1333 if ldd := x64_optional_tool_output(@FN, 'ldd', os.quoted_path(result.bin_path)) {
1334 assert ldd.contains('not a dynamic executable'), '${context}\nldd output:\n${ldd}'
1335 }
1336 if nm := x64_optional_tool_output(@FN, 'nm', '-u ${os.quoted_path(result.bin_path)}') {
1337 assert nm.contains('no symbols') || nm.trim_space() == '', '${context}\nnm -u output:\n${nm}'
1338 }
1339 }
1340}
1341
1342fn assert_x64_linux_hosted_libc_binary(result X64HostRunResult, expected_stdout []u8) {
1343 $if linux {
1344 context := x64_host_result_context(result)
1345 assert result.stdout == expected_stdout, x64_stdout_mismatch_message(result.name, 'linux',
1346 expected_stdout, result.stdout, context)
1347
1348 assert result.stderr == []u8{}, x64_stderr_mismatch_message(result.name, 'linux', []u8{},
1349 result.stderr, context)
1350
1351 if readelf_dynamic := x64_optional_tool_output(@FN, 'readelf',
1352 '-d ${os.quoted_path(result.bin_path)}')
1353 {
1354 assert readelf_dynamic.contains('Dynamic section at offset'), '${context}\nreadelf -d output:\n${readelf_dynamic}'
1355 }
1356 if ldd := x64_optional_tool_output(@FN, 'ldd', os.quoted_path(result.bin_path)) {
1357 assert ldd.contains('libc.so'), '${context}\nldd output:\n${ldd}'
1358 }
1359 if nm := x64_optional_tool_output(@FN, 'nm', '-u ${os.quoted_path(result.bin_path)}') {
1360 assert nm.contains('__libc_start_main') || nm.contains('calloc'), '${context}\nnm -u output:\n${nm}'
1361 }
1362 }
1363}
1364
1365fn assert_x64_linux_load_segment_count(result X64HostRunResult, expected_count int) {
1366 $if linux {
1367 context := x64_host_result_context(result)
1368 actual_count := x64_elf_load_segment_count(result.bin_path)
1369 assert actual_count == expected_count, '${context}\nELF PT_LOAD count: expected ${expected_count}, got ${actual_count}'
1370 }
1371}
1372
1373fn assert_x64_linux_tiny_load_segment_layout(result X64HostRunResult, expected_rw_bss_bytes u64) {
1374 $if linux {
1375 context := x64_host_result_context(result)
1376 segments := x64_elf_load_segments(result.bin_path)
1377 for i, segment in segments {
1378 wx_flags := segment.flags & u32(pf_w | pf_x)
1379 assert wx_flags != u32(pf_w | pf_x), '${context}\nELF PT_LOAD ${i} is writable and executable: flags=0x${segment.flags.hex()}'
1380 assert segment.memsz >= segment.filesz, '${context}\nELF PT_LOAD ${i} memsz ${segment.memsz} is smaller than filesz ${segment.filesz}'
1381 if segment.align > 1 {
1382 assert segment.vaddr % segment.align == segment.offset % segment.align, '${context}\nELF PT_LOAD ${i} offset/vaddr are not congruent modulo align: offset=0x${segment.offset.hex()} vaddr=0x${segment.vaddr.hex()} align=0x${segment.align.hex()}'
1383 }
1384 }
1385 text_segment := segments[0]
1386 assert text_segment.flags == u32(pf_r | pf_x), '${context}\nELF text PT_LOAD flags: expected 0x${u32(pf_r | pf_x).hex()}, got 0x${text_segment.flags.hex()}'
1387 assert text_segment.memsz == text_segment.filesz, '${context}\nELF text PT_LOAD should not contain writable zero-fill: filesz=${text_segment.filesz} memsz=${text_segment.memsz}'
1388 if expected_rw_bss_bytes == 0 {
1389 assert segments.len == 1, '${context}\nELF PT_LOAD count: expected 1, got ${segments.len}'
1390 return
1391 }
1392 assert segments.len == 2, '${context}\nELF PT_LOAD count: expected 2, got ${segments.len}'
1393 rw_segment := segments[1]
1394 assert rw_segment.flags == u32(pf_r | pf_w), '${context}\nELF RW PT_LOAD flags: expected 0x${u32(pf_r | pf_w).hex()}, got 0x${rw_segment.flags.hex()}'
1395 assert rw_segment.filesz == 0, '${context}\nELF RW PT_LOAD for tiny runtime metadata should be zero-fill only: filesz=${rw_segment.filesz}'
1396 assert rw_segment.memsz == expected_rw_bss_bytes, '${context}\nELF RW PT_LOAD bss bytes: expected ${expected_rw_bss_bytes}, got ${rw_segment.memsz}'
1397 }
1398}
1399
1400fn assert_x64_linux_tiny_build_rejected(name string, source string, expected_message string) {
1401 $if linux {
1402 tmp_dir := os.join_path(os.vtmp_dir(), 'v2_x64_runtime_${name}_${os.getpid()}')
1403 os.mkdir_all(tmp_dir) or { panic(err) }
1404 defer {
1405 os.rmdir_all(tmp_dir) or {}
1406 }
1407 source_path := os.join_path(tmp_dir, '${name}.v')
1408 bin_path := x64_host_bin_path(tmp_dir, name)
1409 os.write_file(source_path, source) or { panic(err) }
1410 vexe := x64_vexe_command_path()
1411 mut build := os.new_process(vexe)
1412 defer {
1413 build.close()
1414 }
1415 build.set_environment(x64_strict_tiny_build_environment(vexe, tmp_dir))
1416 build.set_args(['-v2', '-no-parallel', '-b', 'x64', source_path, '-o', bin_path])
1417 build.set_redirect_stdio()
1418 build.run()
1419 build.wait()
1420 build_output := 'stdout:\n${build.stdout_slurp()}\nstderr:\n${build.stderr_slurp()}'
1421 assert build.code != 0, '${name} unexpectedly built with Linux tiny:\n${build_output}'
1422 assert build_output.contains(expected_message), '${name} rejection did not contain `${expected_message}`:\n${build_output}'
1423 assert !os.exists(bin_path), '${name} produced a binary despite Linux tiny rejection: ${bin_path}'
1424 }
1425}
1426
1427fn assert_x64_linux_tiny_project_build_rejected(name string, sources map[string]string, expected_message string) {
1428 $if linux {
1429 tmp_dir := os.join_path(os.vtmp_dir(), 'v2_x64_runtime_${name}_${os.getpid()}')
1430 os.mkdir_all(tmp_dir) or { panic(err) }
1431 defer {
1432 os.rmdir_all(tmp_dir) or {}
1433 }
1434 bin_path := x64_host_bin_path(tmp_dir, name)
1435 x64_write_project_sources(tmp_dir, sources)
1436 vexe := x64_vexe_command_path()
1437 mut build := os.new_process(vexe)
1438 defer {
1439 build.close()
1440 }
1441 build.set_environment(x64_strict_tiny_build_environment(vexe, tmp_dir))
1442 build.set_args(['-v2', '-no-parallel', '-b', 'x64', tmp_dir, '-o', bin_path])
1443 build.set_redirect_stdio()
1444 build.run()
1445 build.wait()
1446 build_output := 'stdout:\n${build.stdout_slurp()}\nstderr:\n${build.stderr_slurp()}'
1447 assert build.code != 0, '${name} unexpectedly built with Linux tiny:\n${build_output}'
1448 assert build_output.contains(expected_message), '${name} rejection did not contain `${expected_message}`:\n${build_output}'
1449 assert !os.exists(bin_path), '${name} produced a binary despite Linux tiny rejection: ${bin_path}'
1450 }
1451}
1452
1453fn assert_x64_macos_windows_stdout_bytes(name string, source string, expected_stdout []u8) {
1454 $if macos {
1455 result := run_x64_host_program_redirected('macos_${name}', source)
1456 context := x64_host_result_context(result)
1457 stdout_message := x64_stdout_mismatch_message(name, 'macos', expected_stdout,
1458 result.stdout, context)
1459 stderr_message := x64_stderr_mismatch_message(name, 'macos', []u8{}, result.stderr, context)
1460 assert result.stdout == expected_stdout, stdout_message
1461 assert result.stderr == []u8{}, stderr_message
1462 x64_host_cleanup_tmp(result.tmp_dir)
1463 }
1464 $if windows {
1465 result := run_x64_host_program_redirected('windows_${name}', source)
1466 context := x64_host_result_context(result)
1467 stdout_message := x64_stdout_mismatch_message(name, 'windows', expected_stdout,
1468 result.stdout, context)
1469 stderr_message := x64_stderr_mismatch_message(name, 'windows', []u8{}, result.stderr,
1470 context)
1471 assert result.stdout == expected_stdout, stdout_message
1472 assert result.stderr == []u8{}, stderr_message
1473 x64_host_cleanup_tmp(result.tmp_dir)
1474 }
1475}
1476
1477fn assert_x64_macos_stdout_bytes(name string, source string, expected_stdout []u8) {
1478 $if macos {
1479 result := run_x64_host_program_redirected('macos_${name}', source)
1480 context := x64_host_result_context(result)
1481 stdout_message := x64_stdout_mismatch_message(name, 'macos', expected_stdout,
1482 result.stdout, context)
1483 stderr_message := x64_stderr_mismatch_message(name, 'macos', []u8{}, result.stderr, context)
1484 assert result.stdout == expected_stdout, stdout_message
1485 assert result.stderr == []u8{}, stderr_message
1486 x64_host_cleanup_tmp(result.tmp_dir)
1487 }
1488}
1489
1490fn assert_x64_windows_stdout_bytes(name string, source string, expected_stdout []u8) {
1491 $if windows {
1492 result := run_x64_host_program_redirected('windows_${name}', source)
1493 context := x64_host_result_context(result)
1494 stdout_message := x64_stdout_mismatch_message(name, 'windows', expected_stdout,
1495 result.stdout, context)
1496 stderr_message := x64_stderr_mismatch_message(name, 'windows', []u8{}, result.stderr,
1497 context)
1498 assert result.stdout == expected_stdout, stdout_message
1499 assert result.stderr == []u8{}, stderr_message
1500 x64_host_cleanup_tmp(result.tmp_dir)
1501 }
1502}
1503
1504fn assert_x64_macos_windows_file_stdout_bytes(name string, source_dir string, source_file string, expected_stdout []u8) {
1505 $if macos {
1506 result := run_x64_host_file_redirected('macos_${name}', source_dir, source_file)
1507 context := x64_host_result_context(result)
1508 stdout_message := x64_stdout_mismatch_message(name, 'macos', expected_stdout,
1509 result.stdout, context)
1510 stderr_message := x64_stderr_mismatch_message(name, 'macos', []u8{}, result.stderr, context)
1511 assert result.stdout == expected_stdout, stdout_message
1512 assert result.stderr == []u8{}, stderr_message
1513 x64_host_cleanup_tmp(result.tmp_dir)
1514 }
1515 $if windows {
1516 result := run_x64_host_file_redirected('windows_${name}', source_dir, source_file)
1517 context := x64_host_result_context(result)
1518 stdout_message := x64_stdout_mismatch_message(name, 'windows', expected_stdout,
1519 result.stdout, context)
1520 stderr_message := x64_stderr_mismatch_message(name, 'windows', []u8{}, result.stderr,
1521 context)
1522 assert result.stdout == expected_stdout, stdout_message
1523 assert result.stderr == []u8{}, stderr_message
1524 x64_host_cleanup_tmp(result.tmp_dir)
1525 }
1526}
1527
1528fn assert_x64_macos_windows_exit_code_stdout_stderr(name string, source string, exit_code int, expected_stdout []u8, expected_stderr []u8) {
1529 $if macos {
1530 result := run_x64_host_program_redirected_with_exit('macos_${name}', source)
1531 context := x64_host_exit_result_context(result)
1532 exit_message := x64_exit_code_mismatch_message(name, 'macos', exit_code, result.exit_code,
1533 result.stdout, result.stderr, context)
1534 stdout_message := x64_stdout_mismatch_message(name, 'macos', expected_stdout,
1535 result.stdout, context)
1536 stderr_message := x64_stderr_mismatch_message(name, 'macos', expected_stderr,
1537 result.stderr, context)
1538 assert result.exit_code == exit_code, exit_message
1539 assert result.stdout == expected_stdout, stdout_message
1540 assert result.stderr == expected_stderr, stderr_message
1541 x64_host_cleanup_tmp(result.tmp_dir)
1542 }
1543 $if windows {
1544 result := run_x64_host_program_redirected_with_exit('windows_${name}', source)
1545 context := x64_host_exit_result_context(result)
1546 exit_message := x64_exit_code_mismatch_message(name, 'windows', exit_code,
1547 result.exit_code, result.stdout, result.stderr, context)
1548 stdout_message := x64_stdout_mismatch_message(name, 'windows', expected_stdout,
1549 result.stdout, context)
1550 stderr_message := x64_stderr_mismatch_message(name, 'windows', expected_stderr,
1551 result.stderr, context)
1552 assert result.exit_code == exit_code, exit_message
1553 assert result.stdout == expected_stdout, stdout_message
1554 assert result.stderr == expected_stderr, stderr_message
1555 x64_host_cleanup_tmp(result.tmp_dir)
1556 }
1557}
1558
1559fn assert_x64_windows_exit_code_stdout_stderr(name string, source string, exit_code int, expected_stdout []u8, expected_stderr []u8) {
1560 $if windows {
1561 result := run_x64_host_program_redirected_with_exit('windows_${name}', source)
1562 context := x64_host_exit_result_context(result)
1563 exit_message := x64_exit_code_mismatch_message(name, 'windows', exit_code,
1564 result.exit_code, result.stdout, result.stderr, context)
1565 stdout_message := x64_stdout_mismatch_message(name, 'windows', expected_stdout,
1566 result.stdout, context)
1567 stderr_message := x64_stderr_mismatch_message(name, 'windows', expected_stderr,
1568 result.stderr, context)
1569 assert result.exit_code == exit_code, exit_message
1570 assert result.stdout == expected_stdout, stdout_message
1571 assert result.stderr == expected_stderr, stderr_message
1572 x64_host_cleanup_tmp(result.tmp_dir)
1573 }
1574}
1575
1576fn assert_x64_linux_project_stdout_bytes(name string, sources map[string]string, expected_stdout []u8) {
1577 $if linux {
1578 result := run_x64_linux_project_redirected(name, sources)
1579 assert result.stdout == expected_stdout, '${name} stdout mismatch: ${result.stdout}'
1580 assert result.stderr == []u8{}, '${name} stderr mismatch: ${result.stderr}'
1581 }
1582}
1583
1584fn assert_x64_macos_windows_project_stdout_bytes(name string, sources map[string]string, expected_stdout []u8) {
1585 $if macos {
1586 result := run_x64_host_project_redirected('macos_${name}', sources)
1587 context := x64_host_result_context(result)
1588 stdout_message := x64_stdout_mismatch_message(name, 'macos', expected_stdout,
1589 result.stdout, context)
1590 stderr_message := x64_stderr_mismatch_message(name, 'macos', []u8{}, result.stderr, context)
1591 assert result.stdout == expected_stdout, stdout_message
1592 assert result.stderr == []u8{}, stderr_message
1593 x64_host_cleanup_tmp(result.tmp_dir)
1594 }
1595 $if windows {
1596 result := run_x64_host_project_redirected('windows_${name}', sources)
1597 context := x64_host_result_context(result)
1598 stdout_message := x64_stdout_mismatch_message(name, 'windows', expected_stdout,
1599 result.stdout, context)
1600 stderr_message := x64_stderr_mismatch_message(name, 'windows', []u8{}, result.stderr,
1601 context)
1602 assert result.stdout == expected_stdout, stdout_message
1603 assert result.stderr == []u8{}, stderr_message
1604 x64_host_cleanup_tmp(result.tmp_dir)
1605 }
1606}
1607
1608fn x64_getwd_clone_source() string {
1609 return "module main
1610
1611import os
1612
1613fn main() {
1614 wd := os.getwd()
1615 if wd.len > 0 {
1616 println('ok')
1617 } else {
1618 println('bad')
1619 }
1620}
1621"
1622}
1623
1624fn x64_getwd_clone_stdout() []u8 {
1625 return 'ok
1626'.bytes()
1627}
1628
1629fn x64_escaped_local_u8_pointer_source() string {
1630 return "module main
1631
1632fn emit(p &u8) {
1633 if unsafe { *p } == u8(88) {
1634 print('X')
1635 return
1636 }
1637 print('!')
1638}
1639
1640fn main() {
1641 ch := u8(88)
1642 emit(&ch)
1643}
1644"
1645}
1646
1647fn x64_escaped_local_u8_pointer_stdout() []u8 {
1648 return [u8(`X`)]
1649}
1650
1651fn x64_logical_and_backward_false_branch_source() string {
1652 return "module main
1653
1654fn status(fd int) int {
1655 if fd != 1 && fd != 2 {
1656 return 1
1657 }
1658 return 0
1659}
1660
1661fn main() {
1662 if status(1) != 0 {
1663 println('bad-1')
1664 return
1665 }
1666 if status(2) != 0 {
1667 println('bad-2')
1668 return
1669 }
1670 if status(3) != 1 {
1671 println('bad-3')
1672 return
1673 }
1674 println('ok')
1675}
1676"
1677}
1678
1679fn x64_logical_and_backward_false_branch_stdout() []u8 {
1680 return 'ok
1681'.bytes()
1682}
1683
1684fn x64_status_short_circuit_calls_source() string {
1685 return "module main
1686
1687fn status(fd int) int {
1688 if fd != 1 && fd != 2 {
1689 return 1
1690 }
1691 return 0
1692}
1693
1694fn main() {
1695 if status(1) == 0 && status(2) == 0 && status(3) == 1 {
1696 println('K')
1697 } else {
1698 println('k')
1699 }
1700}
1701"
1702}
1703
1704fn x64_status_short_circuit_calls_stdout() []u8 {
1705 return 'K
1706'.bytes()
1707}
1708
1709fn x64_dump_operator_identity_source() string {
1710 return "module main
1711
1712fn pass_u32(x u32) u32 {
1713 y := x + u32(5)
1714 return dump(y)
1715}
1716
1717fn main() {
1718 if dump(false) {
1719 println('bad-bool')
1720 return
1721 }
1722 mut n := u32(1)
1723 old := dump(n++)
1724 if old == u32(1) && n == u32(2) && pass_u32(u32(7)) == u32(12) {
1725 println('ok')
1726 } else {
1727 println('bad')
1728 }
1729}
1730"
1731}
1732
1733fn x64_dump_operator_identity_stdout() []u8 {
1734 return 'ok
1735'.bytes()
1736}
1737
1738fn x64_dump_factorial_example_stdout() []u8 {
1739 return '120
1740'.bytes()
1741}
1742
1743fn x64_print_stdout_source() string {
1744 return "module main
1745
1746fn main() {
1747 print('X')
1748}
1749"
1750}
1751
1752fn x64_print_stdout() []u8 {
1753 return [u8(`X`)]
1754}
1755
1756fn x64_println_empty_stdout_source() string {
1757 return "module main
1758
1759fn main() {
1760 println('')
1761}
1762"
1763}
1764
1765fn x64_println_empty_stdout() []u8 {
1766 return [u8(`\n`)]
1767}
1768
1769fn x64_println_stdout_source() string {
1770 return "module main
1771
1772fn main() {
1773 println('X')
1774}
1775"
1776}
1777
1778fn x64_println_stdout() []u8 {
1779 return [
1780 u8(`X`),
1781 u8(`\n`),
1782 ]
1783}
1784
1785fn x64_println_string_parameter_stdout_source() string {
1786 return "module main
1787
1788fn emit(s string) {
1789 println(s)
1790}
1791
1792fn main() {
1793 emit('X')
1794}
1795"
1796}
1797
1798fn x64_println_string_parameter_stdout() []u8 {
1799 return [
1800 u8(`X`),
1801 u8(`\n`),
1802 ]
1803}
1804
1805fn x64_i64_loop_carried_mutable_state_source() string {
1806 return "module main
1807
1808fn main() {
1809 mut n := i64(1)
1810 mut index := 20
1811 for n > 0 {
1812 n1 := n / i64(10)
1813 n = n1
1814 index--
1815 }
1816 if index == 19 {
1817 print('O')
1818 } else {
1819 print('B')
1820 }
1821}
1822"
1823}
1824
1825fn x64_i64_loop_carried_mutable_state_stdout() []u8 {
1826 return [u8(`O`)]
1827}
1828
1829fn x64_print_integer_and_int_str_source() string {
1830 return 'module main
1831
1832fn main() {
1833 print(0)
1834 print(1)
1835 n := 23
1836 s := n.str()
1837 println(s)
1838}
1839'
1840}
1841
1842fn x64_print_integer_and_int_str_stdout() []u8 {
1843 return [
1844 u8(`0`),
1845 u8(`1`),
1846 u8(`2`),
1847 u8(`3`),
1848 u8(`\n`),
1849 ]
1850}
1851
1852fn x64_string_index_byte_ascii_str_return_source() string {
1853 return "module main
1854
1855fn first_byte_as_string(s string) string {
1856 b := s[0]
1857 return b.ascii_str()
1858}
1859
1860fn main() {
1861 print(first_byte_as_string('Vlang'))
1862}
1863"
1864}
1865
1866fn x64_string_index_byte_ascii_str_return_stdout() []u8 {
1867 return [u8(`V`)]
1868}
1869
1870fn x64_narrow_integer_call_result_normalization_source() string {
1871 return "module main
1872
1873fn return_u8() u8 {
1874 return u8(250)
1875}
1876
1877fn return_i8() i8 {
1878 return i8(-7)
1879}
1880
1881fn return_u16() u16 {
1882 return u16(65000)
1883}
1884
1885fn return_i16() i16 {
1886 return i16(-1234)
1887}
1888
1889fn return_u32() u32 {
1890 return u32(4000000000)
1891}
1892
1893fn return_i32() i32 {
1894 return i32(-2000000000)
1895}
1896
1897fn return_bool_true() bool {
1898 return true
1899}
1900
1901fn return_bool_false() bool {
1902 return false
1903}
1904
1905fn main() {
1906 if return_u8() == u8(250) {
1907 print('U')
1908 } else {
1909 print('u')
1910 }
1911 if return_i8() == i8(-7) {
1912 print('I')
1913 } else {
1914 print('i')
1915 }
1916 if return_u16() == u16(65000) {
1917 print('W')
1918 } else {
1919 print('w')
1920 }
1921 if return_i16() == i16(-1234) {
1922 print('H')
1923 } else {
1924 print('h')
1925 }
1926 if return_u32() == u32(4000000000) {
1927 print('D')
1928 } else {
1929 print('d')
1930 }
1931 if return_i32() == i32(-2000000000) {
1932 print('N')
1933 } else {
1934 print('n')
1935 }
1936 if return_bool_true() && !return_bool_false() {
1937 println('B')
1938 } else {
1939 println('b')
1940 }
1941}
1942"
1943}
1944
1945fn x64_narrow_integer_call_result_normalization_stdout() []u8 {
1946 return 'UIWHDNB
1947'.bytes()
1948}
1949
1950fn x64_string_equality_inequality_source() string {
1951 return "module main
1952
1953fn main() {
1954 left := 'alpha'
1955 same := 'alpha'
1956 different := 'alpHb'
1957 if left == same {
1958 print('E')
1959 } else {
1960 print('e')
1961 }
1962 if left != different {
1963 print('N')
1964 } else {
1965 print('n')
1966 }
1967 if left == different {
1968 println('b')
1969 } else {
1970 println('B')
1971 }
1972}
1973"
1974}
1975
1976fn x64_string_equality_inequality_stdout() []u8 {
1977 return 'ENB
1978'.bytes()
1979}
1980
1981fn x64_fixed_u8_array_equality_inequality_memcmp_source() string {
1982 return "module main
1983
1984fn main() {
1985 a := [u8(65), 66, 67]!
1986 b := [u8(65), 66, 67]!
1987 c := [u8(65), 66, 68]!
1988 if a == b {
1989 print('A')
1990 } else {
1991 print('a')
1992 }
1993 if a != c {
1994 println('D')
1995 } else {
1996 println('d')
1997 }
1998}
1999"
2000}
2001
2002fn x64_fixed_u8_array_equality_inequality_memcmp_stdout() []u8 {
2003 return 'AD
2004'.bytes()
2005}
2006
2007fn x64_heap_alloc_zeroed_struct_literal_source() string {
2008 return "module main
2009
2010struct HeapBox {
2011 a int
2012 b int
2013 flag bool
2014 byte u8
2015}
2016
2017fn make_box() &HeapBox {
2018 return &HeapBox{
2019 a: 7
2020 }
2021}
2022
2023fn main() {
2024 box := make_box()
2025 if box.a == 7 {
2026 print('A')
2027 } else {
2028 print('a')
2029 }
2030 if box.b == 0 && !box.flag && box.byte == u8(0) {
2031 println('Z')
2032 } else {
2033 println('z')
2034 }
2035}
2036"
2037}
2038
2039fn x64_heap_alloc_zeroed_struct_literal_stdout() []u8 {
2040 return 'AZ
2041'.bytes()
2042}
2043
2044fn x64_generic_sumtype_direct_wrap_source() string {
2045 return "module main
2046
2047struct Empty {}
2048
2049struct Node[T] {
2050 value T
2051 left Tree[T]
2052 right Tree[T]
2053}
2054
2055type Tree[T] = Empty | Node[T]
2056
2057fn tag(tree Tree[f64]) int {
2058 return match tree {
2059 Empty { 0 }
2060 Node[f64] { 1 }
2061 }
2062}
2063
2064fn payload_score(tree Tree[f64]) int {
2065 return match tree {
2066 Empty { 0 }
2067 Node[f64] {
2068 if tree.value == 8.0 {
2069 10 + tag(tree.left) + tag(tree.right)
2070 } else {
2071 -1
2072 }
2073 }
2074 }
2075}
2076
2077fn main() {
2078 empty := Tree[f64](Empty{})
2079 tree := Tree[f64](Node[f64]{8.0, empty, empty})
2080 if tag(empty) == 0 {
2081 print('E')
2082 } else {
2083 print('e')
2084 }
2085 if tag(tree) == 1 {
2086 print('N')
2087 } else {
2088 print('n')
2089 }
2090 if payload_score(tree) == 10 {
2091 println('P')
2092 } else {
2093 println('p')
2094 }
2095}
2096"
2097}
2098
2099fn x64_generic_sumtype_direct_wrap_stdout() []u8 {
2100 return 'ENP
2101'.bytes()
2102}
2103
2104fn x64_generic_sumtype_repeated_base_specialization_source() string {
2105 return "module main
2106
2107struct Box[T] {
2108 value T
2109}
2110
2111type Value = Box[int] | Box[string]
2112
2113fn string_tag(value Value) int {
2114 return match value {
2115 Box[string] { 1 }
2116 else { 0 }
2117 }
2118}
2119
2120fn int_tag(value Value) int {
2121 return match value {
2122 Box[int] { 0 }
2123 else { 1 }
2124 }
2125}
2126
2127fn main() {
2128 if string_tag(Value(Box[string]{'ok'})) == 1 {
2129 print('S')
2130 } else {
2131 print('s')
2132 }
2133 if int_tag(Value(Box[int]{7})) == 0 {
2134 println('I')
2135 } else {
2136 println('i')
2137 }
2138}
2139"
2140}
2141
2142fn x64_generic_sumtype_repeated_base_specialization_stdout() []u8 {
2143 return 'SI
2144'.bytes()
2145}
2146
2147fn x64_generic_sumtype_receiver_size_source() string {
2148 return 'module main
2149
2150struct Empty {}
2151
2152struct Node[T] {
2153 value T
2154 left Tree[T]
2155 right Tree[T]
2156}
2157
2158type Tree[T] = Empty | Node[T]
2159
2160fn (tree Tree[T]) size[T]() int {
2161 return match tree {
2162 Empty { 0 }
2163 Node[T] { 1 }
2164 }
2165}
2166
2167fn main() {
2168 empty := Tree[f64](Empty{})
2169 tree := Tree[f64](Node[f64]{1.0, empty, empty})
2170 println(tree.size())
2171}
2172'
2173}
2174
2175fn x64_generic_sumtype_receiver_size_stdout() []u8 {
2176 return '1
2177'.bytes()
2178}
2179
2180fn x64_generic_sumtype_insert_size_source() string {
2181 return 'module main
2182
2183struct Empty {}
2184
2185struct Node[T] {
2186 value T
2187 left Tree[T]
2188 right Tree[T]
2189}
2190
2191type Tree[T] = Empty | Node[T]
2192
2193fn (tree Tree[T]) size[T]() int {
2194 return match tree {
2195 Empty { 0 }
2196 Node[T] { 1 + tree.left.size() + tree.right.size() }
2197 }
2198}
2199
2200fn (tree Tree[T]) insert[T](x T) Tree[T] {
2201 return match tree {
2202 Empty { Node[T]{x, tree, tree} }
2203 Node[T] {
2204 if x == tree.value {
2205 tree
2206 } else if x < tree.value {
2207 Node[T]{ ...tree, left: tree.left.insert(x) }
2208 } else {
2209 Node[T]{ ...tree, right: tree.right.insert(x) }
2210 }
2211 }
2212 }
2213}
2214
2215fn main() {
2216 mut tree := Tree[f64](Empty{})
2217 tree = tree.insert(0.2)
2218 tree = tree.insert(0.5)
2219 println(tree.size())
2220}
2221'
2222}
2223
2224fn x64_generic_sumtype_insert_size_stdout() []u8 {
2225 return '2
2226'.bytes()
2227}
2228
2229fn x64_struct_float_fields_source() string {
2230 return "module main
2231
2232struct FloatBox {
2233 a f64
2234 b f32
2235}
2236
2237fn make_box() FloatBox {
2238 return FloatBox{
2239 a: 8.0
2240 b: f32(2.5)
2241 }
2242}
2243
2244fn main() {
2245 box := make_box()
2246 if box.a == 8.0 {
2247 print('D')
2248 } else {
2249 print('d')
2250 }
2251 if box.b == f32(2.5) {
2252 println('F')
2253 } else {
2254 println('f')
2255 }
2256}
2257"
2258}
2259
2260fn x64_struct_float_fields_stdout() []u8 {
2261 return 'DF
2262'.bytes()
2263}
2264
2265fn x64_union_f64_bits_source() string {
2266 return "module main
2267
2268import strconv
2269
2270fn main() {
2271 marker := 'hosted'.clone()
2272 _ = marker
2273 x := 0.2
2274 u := strconv.Float64u{
2275 f: x
2276 }
2277 unsafe {
2278 if u.u == u64(0) {
2279 println('f_to_u=zero')
2280 } else {
2281 println('f_to_u=nonzero')
2282 }
2283 v := strconv.Float64u{
2284 u: u64(4596373779694328218)
2285 }
2286 if v.f == x {
2287 println('u_to_f=ok')
2288 } else {
2289 println('u_to_f=bad')
2290 }
2291 }
2292}
2293"
2294}
2295
2296fn x64_union_f64_bits_stdout() []u8 {
2297 return 'f_to_u=nonzero
2298u_to_f=ok
2299'.bytes()
2300}
2301
2302fn x64_f64_str_interpolation_source() string {
2303 return "module main
2304
2305fn ok_arg(x f64) int {
2306 if x == 0.2 {
2307 return 1
2308 }
2309 return 0
2310}
2311
2312fn main() {
2313 x := 0.2
2314 println(ok_arg(x))
2315 println(x.str())
2316 println('\${x}')
2317}
2318"
2319}
2320
2321fn x64_f64_str_interpolation_stdout() []u8 {
2322 return '1
23230.2
23240.2
2325'.bytes()
2326}
2327
2328fn x64_f64_for_interpolation_source() string {
2329 return "module main
2330
2331fn main() {
2332 vals := [0.2, 0.0, 0.5, 0.3, 0.6, 0.8]
2333 for i in vals {
2334 if i < 0.7 {
2335 print('\${i} ')
2336 }
2337 }
2338 println('')
2339}
2340"
2341}
2342
2343fn x64_f64_for_interpolation_stdout() []u8 {
2344 return '0.2 0.0 0.5 0.3 0.6 \n'.bytes()
2345}
2346
2347fn x64_formatted_int_interpolation_source() string {
2348 return 'module main
2349
2350fn main() {
2351 println("\${42:04d}")
2352}
2353'
2354}
2355
2356fn x64_formatted_int_interpolation_stdout() []u8 {
2357 return '0042\n'.bytes()
2358}
2359
2360fn x64_formatted_int_width_100_interpolation_source() string {
2361 return 'module main
2362
2363fn main() {
2364 println("\${42:0100d}")
2365}
2366'
2367}
2368
2369fn x64_formatted_int_width_100_interpolation_stdout() []u8 {
2370 return ('0'.repeat(98) + '42\n').bytes()
2371}
2372
2373fn x64_formatted_f64_interpolation_source() string {
2374 return 'module main
2375
2376fn main() {
2377 x := 1.271844019
2378 println("\${x:0.9f}")
2379}
2380'
2381}
2382
2383fn x64_formatted_f64_interpolation_stdout() []u8 {
2384 return '1.271844019\n'.bytes()
2385}
2386
2387fn x64_formatted_string_return_lifetime_source() string {
2388 return 'module main
2389
2390fn make_formatted() string {
2391 return "\${42:04d}"
2392}
2393
2394fn clobber_stack() int {
2395 mut data := [256]u8{}
2396 for i in 0 .. data.len {
2397 data[i] = u8(65 + i % 26)
2398 }
2399 return int(data[0]) + int(data[255])
2400}
2401
2402fn main() {
2403 s := make_formatted()
2404 guard := clobber_stack()
2405 if guard == 0 {
2406 println("bad")
2407 }
2408 println(s)
2409}
2410'
2411}
2412
2413fn x64_formatted_string_return_lifetime_stdout() []u8 {
2414 return '0042\n'.bytes()
2415}
2416
2417fn x64_spectral_reduced_formatted_source() string {
2418 return 'module main
2419
2420import math
2421
2422fn evala(i int, j int) int {
2423 return (i + j) * (i + j + 1) / 2 + i + 1
2424}
2425
2426fn times(mut v []f64, u []f64) {
2427 for i in 0 .. v.len {
2428 mut a := f64(0)
2429 for j in 0 .. u.len {
2430 a += u[j] / f64(evala(i, j))
2431 }
2432 v[i] = a
2433 }
2434}
2435
2436fn times_trans(mut v []f64, u []f64) {
2437 for i in 0 .. v.len {
2438 mut a := f64(0)
2439 for j in 0 .. u.len {
2440 a += u[j] / f64(evala(j, i))
2441 }
2442 v[i] = a
2443 }
2444}
2445
2446fn a_times_transp(mut v []f64, u []f64) {
2447 mut x := []f64{len: u.len, init: 0}
2448 times(mut x, u)
2449 times_trans(mut v, x)
2450}
2451
2452fn main() {
2453 n := 10
2454 mut u := []f64{len: n, init: 1}
2455 mut v := []f64{len: n, init: 1}
2456 for _ in 0 .. 10 {
2457 a_times_transp(mut v, u)
2458 a_times_transp(mut u, v)
2459 }
2460 mut vbv := f64(0)
2461 mut vv := f64(0)
2462 for i in 0 .. n {
2463 vbv += u[i] * v[i]
2464 vv += v[i] * v[i]
2465 }
2466 ans := math.sqrt(vbv / vv)
2467 println("\${ans:0.9f}")
2468}
2469'
2470}
2471
2472fn x64_spectral_reduced_formatted_stdout() []u8 {
2473 return '1.271844019\n'.bytes()
2474}
2475
2476fn x64_bits_len32_source() string {
2477 return 'module main
2478
2479import math.bits
2480
2481fn main() {
2482 println(bits.len_32(10))
2483 println(bits.len_32(1))
2484 println(bits.len_32(0))
2485}
2486'
2487}
2488
2489fn x64_bits_len32_stdout() []u8 {
2490 return '4\n1\n0\n'.bytes()
2491}
2492
2493fn x64_rand_u32n_interface_result_source() string {
2494 return 'module main
2495
2496import rand
2497
2498fn via_rng_u32n(mut rng rand.PRNG, max u32) !u32 {
2499 return rng.u32n(max)
2500}
2501
2502fn main() {
2503 rand.seed([u32(1), 2])
2504 mut rng := rand.get_current_rng()
2505 println("rng.u32n255")
2506 for _ in 0 .. 8 {
2507 println(rng.u32n(255) or { 999999 })
2508 }
2509 rand.seed([u32(1), 2])
2510 println("rand.u32n255")
2511 for _ in 0 .. 8 {
2512 println(rand.u32n(255) or { 999999 })
2513 }
2514 rand.seed([u32(1), 2])
2515 mut via_rng := rand.get_current_rng()
2516 println("via_rng_u32n255")
2517 for _ in 0 .. 8 {
2518 println(via_rng_u32n(mut via_rng, 255) or { 999999 })
2519 }
2520}
2521'
2522}
2523
2524fn x64_rand_u32n_interface_result_stdout() []u8 {
2525 return 'rng.u32n255\n72\n99\n113\n97\n151\n9\n250\n120\nrand.u32n255\n72\n99\n113\n97\n151\n9\n250\n120\nvia_rng_u32n255\n72\n99\n113\n97\n151\n9\n250\n120\n'.bytes()
2526}
2527
2528fn x64_rand_intn_range_interface_result_source() string {
2529 return 'module main
2530
2531import rand
2532
2533fn main() {
2534 rand.seed([u32(1), 2])
2535 mut rng_direct := rand.get_current_rng()
2536 println("direct.int.from.rng.u32n255")
2537 println(int(rng_direct.u32n(u32(255)) or { 999999 }))
2538 rand.seed([u32(1), 2])
2539 mut rng_intn := rand.get_current_rng()
2540 println("rng.intn255")
2541 for _ in 0 .. 8 {
2542 println(rng_intn.intn(255) or { 999999 })
2543 }
2544 rand.seed([u32(1), 2])
2545 println("rand.intn255")
2546 for _ in 0 .. 8 {
2547 println(rand.intn(255) or { 999999 })
2548 }
2549 rand.seed([u32(1), 2])
2550 println("rand.int_in_range_5_15")
2551 for _ in 0 .. 8 {
2552 println(rand.int_in_range(5, 15) or { 999999 })
2553 }
2554}
2555'
2556}
2557
2558fn x64_rand_intn_range_interface_result_stdout() []u8 {
2559 return 'direct.int.from.rng.u32n255\n72\nrng.intn255\n72\n99\n113\n97\n151\n9\n250\n120\nrand.intn255\n72\n99\n113\n97\n151\n9\n250\n120\nrand.int_in_range_5_15\n13\n8\n6\n14\n8\n9\n5\n11\n'.bytes()
2560}
2561
2562fn x64_custom_error_result_or_block_source() string {
2563 return 'module main
2564
2565struct MyErr {
2566 Error
2567}
2568
2569struct OtherErr {
2570 Error
2571}
2572
2573struct MessageLike {}
2574
2575fn (m MessageLike) msg() string {
2576 return "message-like"
2577}
2578
2579fn fail_direct() !int {
2580 return &MyErr{}
2581}
2582
2583fn fail_cast() !int {
2584 return IError(&MyErr{})
2585}
2586
2587fn fail_other() !int {
2588 return &OtherErr{}
2589}
2590
2591fn fail_builtin() !int {
2592 return error("x")
2593}
2594
2595fn inner() !int {
2596 return &MyErr{}
2597}
2598
2599fn propagate() !int {
2600 inner() or {
2601 return err
2602 }
2603 return 0
2604}
2605
2606fn ok_ierror(e IError) !IError {
2607 return e
2608}
2609
2610fn ok_option_ierror(e IError) ?IError {
2611 return e
2612}
2613
2614fn classify_my_only(err IError) string {
2615 match err {
2616 MyErr {
2617 return "my"
2618 }
2619 else {
2620 return "not-my"
2621 }
2622 }
2623}
2624
2625fn classify_full(err IError) string {
2626 match err {
2627 MyErr {
2628 return "my"
2629 }
2630 OtherErr {
2631 return "other"
2632 }
2633 else {
2634 return "builtin"
2635 }
2636 }
2637}
2638
2639fn classify_is_my(err IError) string {
2640 if err is MyErr {
2641 return "is-my"
2642 }
2643 return "not-is-my"
2644}
2645
2646fn classify_not_my(err IError) string {
2647 if err !is MyErr {
2648 return "not-is-my"
2649 }
2650 return "is-my"
2651}
2652
2653fn main() {
2654 fail_direct() or {
2655 println("direct:" + classify_my_only(err))
2656 println("direct-is:" + classify_is_my(err))
2657 }
2658 fail_cast() or {
2659 println("cast:" + classify_my_only(err))
2660 }
2661 fail_other() or {
2662 println("other:" + classify_my_only(err))
2663 println("other-full:" + classify_full(err))
2664 println("other-not-is:" + classify_not_my(err))
2665 }
2666 fail_builtin() or {
2667 println("builtin:" + classify_my_only(err))
2668 println("builtin-full:" + classify_full(err))
2669 }
2670 propagate() or {
2671 println("propagate:" + classify_my_only(err))
2672 }
2673 ok_ierror(IError(&MyErr{})) or {
2674 println("bad-result-ierror")
2675 return
2676 }
2677 println("result-ierror:ok")
2678 ok_option_ierror(IError(&MyErr{})) or {
2679 println("bad-option-ierror")
2680 return
2681 }
2682 println("option-ierror:ok")
2683 msg_like := MessageLike{}
2684 println("message-like:" + msg_like.msg())
2685 println("done")
2686}
2687'
2688}
2689
2690fn x64_custom_error_result_or_block_stdout() []u8 {
2691 return 'direct:my\ndirect-is:is-my\ncast:my\nother:not-my\nother-full:other\nother-not-is:not-is-my\nbuiltin:not-my\nbuiltin-full:builtin\npropagate:my\nresult-ierror:ok\noption-ierror:ok\nmessage-like:message-like\ndone\n'.bytes()
2692}
2693
2694fn x64_custom_error_imported_type_match_sources() map[string]string {
2695 return {
2696 'main.v': 'module main
2697
2698import dep
2699
2700struct LocalErr {
2701 Error
2702}
2703
2704fn fail_local() !int {
2705 return &LocalErr{}
2706}
2707
2708fn fail_import_cast() !int {
2709 return IError(&dep.ForeignErr{})
2710}
2711
2712fn classify(err IError) string {
2713 match err {
2714 dep.ForeignErr {
2715 return "dep.ForeignErr"
2716 }
2717 dep.LocalErr {
2718 return "dep.LocalErr"
2719 }
2720 LocalErr {
2721 return "main.LocalErr"
2722 }
2723 else {
2724 return "other"
2725 }
2726 }
2727}
2728
2729fn main() {
2730 dep.fail_foreign() or {
2731 println("foreign:" + classify(err))
2732 }
2733 fail_import_cast() or {
2734 println("foreign-cast:" + classify(err))
2735 }
2736 dep.fail_local() or {
2737 println("dep-local:" + classify(err))
2738 }
2739 fail_local() or {
2740 println("local:" + classify(err))
2741 }
2742 println("done")
2743}
2744'
2745 'dep/dep.v': 'module dep
2746
2747pub struct ForeignErr {
2748 Error
2749}
2750
2751pub struct LocalErr {
2752 Error
2753}
2754
2755pub fn fail_foreign() !int {
2756 return &ForeignErr{}
2757}
2758
2759pub fn fail_local() !int {
2760 return &LocalErr{}
2761}
2762'
2763 }
2764}
2765
2766fn x64_custom_error_imported_type_match_stdout() []u8 {
2767 return 'foreign:dep.ForeignErr\nforeign-cast:dep.ForeignErr\ndep-local:dep.LocalErr\nlocal:main.LocalErr\ndone\n'.bytes()
2768}
2769
2770fn x64_core_int_control_flow_source() string {
2771 return "module main
2772
2773fn add(a int, b int) int {
2774 return a + b
2775}
2776
2777fn sub(a int, b int) int {
2778 return a - b
2779}
2780
2781fn mul_add(a int, b int, c int) int {
2782 return a * b + c
2783}
2784
2785fn choose(a int, b int) int {
2786 if a > b {
2787 return a
2788 }
2789 return b
2790}
2791
2792fn nested_score(x int) int {
2793 return add(choose(x, 3), mul_add(2, 4, 1))
2794}
2795
2796fn bounded_sum(n int) int {
2797 mut i := 0
2798 mut total := 0
2799 for i < n {
2800 total += i
2801 i += 1
2802 }
2803 return total
2804}
2805
2806fn main() {
2807 if add(19, 23) == 42 && sub(19, 23) == -4 && mul_add(6, 7, -2) == 40 {
2808 print('A')
2809 } else {
2810 print('a')
2811 }
2812 if choose(3, 9) == 9 && choose(10, 4) == 10 {
2813 print('I')
2814 } else {
2815 print('i')
2816 }
2817 if bounded_sum(6) == 15 {
2818 print('L')
2819 } else {
2820 print('l')
2821 }
2822 if nested_score(7) == 16 && nested_score(2) == 12 {
2823 print('N')
2824 } else {
2825 print('n')
2826 }
2827 if 5 < 9 && 9 >= 9 && 4 != 6 {
2828 println('C')
2829 } else {
2830 println('c')
2831 }
2832}
2833"
2834}
2835
2836fn x64_core_int_control_flow_stdout() []u8 {
2837 return 'AILNC
2838'.bytes()
2839}
2840
2841fn x64_stack_args_signed_comparisons_source() string {
2842 return "module main
2843
2844fn tail8_signature(a int, b int, c int, d int, e int, f int, g int, h int) int {
2845 return (a - b) + (c - d) + (e - f) + g * 1000 + h * 10
2846}
2847
2848fn main() {
2849 if tail8_signature(1, 2, 3, 4, 5, 6, 7, 8) == 7077 {
2850 print('T')
2851 } else {
2852 print('t')
2853 }
2854 if -3 < -2 {
2855 print('L')
2856 } else {
2857 print('l')
2858 }
2859 if -1 <= 0 {
2860 print('E')
2861 } else {
2862 print('e')
2863 }
2864 if 0 > -1 {
2865 print('G')
2866 } else {
2867 print('g')
2868 }
2869 if -2 >= -2 {
2870 println('H')
2871 } else {
2872 println('h')
2873 }
2874}
2875"
2876}
2877
2878fn x64_stack_args_signed_comparisons_stdout() []u8 {
2879 return 'TLEGH
2880'.bytes()
2881}
2882
2883fn x64_integer_div_mod_shift_bitwise_source() string {
2884 return "module main
2885
2886fn div_part(a int, b int) int {
2887 return a / b
2888}
2889
2890fn mod_part(a int, b int) int {
2891 return a % b
2892}
2893
2894fn shift_mix(left int, lbits int, positive_right int, negative_right int, rbits int) int {
2895 return (left << lbits) + (positive_right >> rbits) + (negative_right >> rbits)
2896}
2897
2898fn bitwise_mix(a int, b int) int {
2899 return (a & b) * 100 + (a | b) * 10 + (a ^ b)
2900}
2901
2902fn main() {
2903 if div_part(29, 5) == 5 {
2904 print('D')
2905 } else {
2906 print('d')
2907 }
2908 if mod_part(29, 5) == 4 {
2909 print('M')
2910 } else {
2911 print('m')
2912 }
2913 if shift_mix(3, 4, 128, -32, 2) == 72 {
2914 print('S')
2915 } else {
2916 print('s')
2917 }
2918 if bitwise_mix(12, 10) == 946 {
2919 println('B')
2920 } else {
2921 println('b')
2922 }
2923}
2924"
2925}
2926
2927fn x64_integer_div_mod_shift_bitwise_stdout() []u8 {
2928 return 'DMSB
2929'.bytes()
2930}
2931
2932fn x64_structs_fixed_arrays_source() string {
2933 return "module main
2934
2935struct Point {
2936mut:
2937 x int
2938 y int
2939}
2940
2941fn make_point(x int, y int) Point {
2942 return Point{
2943 x: x
2944 y: y
2945 }
2946}
2947
2948fn point_score(p Point) int {
2949 return p.x * 10 + p.y
2950}
2951
2952fn main() {
2953 defaulted := Point{
2954 x: 4
2955 }
2956 if point_score(defaulted) == 40 {
2957 print('S')
2958 } else {
2959 print('s')
2960 }
2961 if make_point(8, 9).y == 9 {
2962 print('E')
2963 } else {
2964 print('e')
2965 }
2966 mut moved := Point{
2967 x: 2
2968 y: 3
2969 }
2970 moved.x = moved.x + 5
2971 moved.y = moved.y * 2
2972 if point_score(moved) == 76 {
2973 print('M')
2974 } else {
2975 print('m')
2976 }
2977 mut src := [3]u8{}
2978 src[0] = 3
2979 src[1] = 5
2980 src[2] = 7
2981 if src[0] == 3 && src[1] == 5 && src[2] == 7 {
2982 print('F')
2983 } else {
2984 print('f')
2985 }
2986 mut dst := [3]u8{}
2987 dst = src
2988 if dst[0] == 3 && dst[1] == 5 && dst[2] == 7 {
2989 println('A')
2990 } else {
2991 println('a')
2992 }
2993}
2994"
2995}
2996
2997fn x64_structs_fixed_arrays_stdout() []u8 {
2998 return 'SEMFA
2999'.bytes()
3000}
3001
3002fn x64_sysv_sse_mixed_aggregates_source() string {
3003 return "module main
3004
3005struct I64F64 {
3006 a i64
3007 b f64
3008}
3009
3010struct F64I64 {
3011 a f64
3012 b i64
3013}
3014
3015struct F64F64 {
3016 a f64
3017 b f64
3018}
3019
3020struct Big {
3021 a i64
3022 b i64
3023 c i64
3024}
3025
3026fn make_i64_f64(a i64, b f64) I64F64 {
3027 return I64F64{
3028 a: a
3029 b: b
3030 }
3031}
3032
3033fn make_f64_i64(a f64, b i64) F64I64 {
3034 return F64I64{
3035 a: a
3036 b: b
3037 }
3038}
3039
3040fn make_f64_f64(a f64, b f64) F64F64 {
3041 return F64F64{
3042 a: a
3043 b: b
3044 }
3045}
3046
3047fn take_i64_f64(v I64F64) bool {
3048 return v.a == 7 && v.b == 2.5
3049}
3050
3051fn take_f64_i64(v F64I64) bool {
3052 return v.a == 3.5 && v.b == 11
3053}
3054
3055fn take_f64_f64(v F64F64) bool {
3056 return v.a == 1.25 && v.b == 6.75
3057}
3058
3059fn take_int_then_f64_f64(n i64, v F64F64) bool {
3060 return n == 5 && v.a == 1.25 && v.b == 6.75
3061}
3062
3063fn make_big_from_mixed(v I64F64) Big {
3064 if v.a == 9 && v.b == 4.5 {
3065 return Big{
3066 a: 12
3067 b: 13
3068 c: 14
3069 }
3070 }
3071 return Big{
3072 a: 1
3073 b: 2
3074 c: 3
3075 }
3076}
3077
3078fn main() {
3079 mixed := make_i64_f64(7, 2.5)
3080 swapped := make_f64_i64(3.5, 11)
3081 pair := make_f64_f64(1.25, 6.75)
3082 if mixed.a == 7 && mixed.b == 2.5 && swapped.a == 3.5 && swapped.b == 11
3083 && pair.a == 1.25 && pair.b == 6.75 {
3084 print('R')
3085 } else {
3086 print('r')
3087 }
3088 if take_i64_f64(mixed) && take_f64_i64(swapped) && take_f64_f64(pair) {
3089 print('A')
3090 } else {
3091 print('a')
3092 }
3093 big := make_big_from_mixed(make_i64_f64(9, 4.5))
3094 if big.a == 12 && big.b == 13 && big.c == 14 {
3095 print('S')
3096 } else {
3097 print('s')
3098 }
3099 if take_int_then_f64_f64(5, pair) {
3100 println('P')
3101 } else {
3102 println('p')
3103 }
3104}
3105"
3106}
3107
3108fn x64_sysv_sse_mixed_aggregates_stdout() []u8 {
3109 return 'RASP
3110'.bytes()
3111}
3112
3113fn x64_fixed_int_array_variable_index_source() string {
3114 return "module main
3115
3116fn poison_fixed20() [20]int {
3117 mut a := [20]int{}
3118 mut i := 0
3119 for i < 20 {
3120 a[i] = 100 + i
3121 i += 1
3122 }
3123 return a
3124}
3125
3126fn zero_fixed20() [20]int {
3127 z := [20]int{}
3128 return z
3129}
3130
3131fn main() {
3132 mut src := [4]int{}
3133 mut i := 0
3134 for i < 4 {
3135 src[i] = (i + 1) * 3
3136 i += 1
3137 }
3138 mut dst := [4]int{}
3139 dst = src
3140 mut j := 0
3141 mut sum := 0
3142 for j < 4 {
3143 sum += dst[j]
3144 j += 1
3145 }
3146 if sum == 30 && dst[0] == 3 && dst[3] == 12 {
3147 print('F')
3148 } else {
3149 print('f')
3150 }
3151 idx := 2
3152 dst[idx] = dst[idx] + 5
3153 mut k := 0
3154 mut adjusted := 0
3155 for k < 4 {
3156 adjusted += dst[k]
3157 k += 1
3158 }
3159 if dst[2] == 14 && adjusted == 35 {
3160 print('V')
3161 } else {
3162 print('v')
3163 }
3164 if src[0] == 3 && src[1] == 6 && src[2] == 9 && src[3] == 12 {
3165 print('I')
3166 } else {
3167 print('i')
3168 }
3169 poisoned := poison_fixed20()
3170 zeroed := zero_fixed20()
3171 mut zidx := 0
3172 mut zsum := 0
3173 for zidx < 20 {
3174 zsum += zeroed[zidx]
3175 zidx += 1
3176 }
3177 if poisoned[0] == 100 && poisoned[19] == 119 && zeroed[0] == 0 && zeroed[19] == 0
3178 && zsum == 0 {
3179 println('Z')
3180 } else {
3181 println('z')
3182 }
3183}
3184"
3185}
3186
3187fn x64_fixed_int_array_variable_index_stdout() []u8 {
3188 return 'FVIZ
3189'.bytes()
3190}
3191
3192fn x64_large_empty_fixed_u8_array_zero_source() string {
3193 return "module main
3194
3195fn poison17() [17]u8 {
3196 mut a := [17]u8{}
3197 mut i := 0
3198 for i < 17 {
3199 a[i] = u8(i + 10)
3200 i += 1
3201 }
3202 return a
3203}
3204
3205fn poison64() [64]u8 {
3206 mut a := [64]u8{}
3207 mut i := 0
3208 for i < 64 {
3209 a[i] = u8(i + 30)
3210 i += 1
3211 }
3212 return a
3213}
3214
3215fn zero17() [17]u8 {
3216 return [17]u8{}
3217}
3218
3219fn zero64() [64]u8 {
3220 z := [64]u8{}
3221 return z
3222}
3223
3224fn main() {
3225 p17 := poison17()
3226 p64 := poison64()
3227 if p17[0] == 10 && p17[16] == 26 && p64[0] == 30 && p64[63] == 93 {
3228 print('P')
3229 } else {
3230 print('p')
3231 }
3232 a := zero17()
3233 b := zero64()
3234 mut i := 0
3235 mut sum17 := 0
3236 for i < 17 {
3237 sum17 += int(a[i])
3238 i += 1
3239 }
3240 mut j := 0
3241 mut sum64 := 0
3242 for j < 64 {
3243 sum64 += int(b[j])
3244 j += 1
3245 }
3246 if a[0] == 0 && a[16] == 0 && sum17 == 0 {
3247 print('Z')
3248 } else {
3249 print('z')
3250 }
3251 if b[0] == 0 && b[17] == 0 && b[63] == 0 && sum64 == 0 {
3252 println('B')
3253 } else {
3254 println('b')
3255 }
3256}
3257"
3258}
3259
3260fn x64_large_empty_fixed_u8_array_zero_stdout() []u8 {
3261 return 'PZB
3262'.bytes()
3263}
3264
3265fn x64_fixed_array_slice_copy_source() string {
3266 return "module main
3267
3268fn main() {
3269 mut f := [5]int{}
3270 f[0] = 2
3271 f[1] = 4
3272 f[2] = 6
3273 f[3] = 8
3274 f[4] = 10
3275 mut a := f[1..4]
3276 if a.len == 3 && a[0] == 4 && a[1] == 6 && a[2] == 8 {
3277 print('S')
3278 } else {
3279 print('s')
3280 }
3281 a[1] = 9
3282 if a[1] == 9 && f[2] == 6 {
3283 print('C')
3284 } else {
3285 print('c')
3286 }
3287 f[2] = 60
3288 a << 12
3289 if a.len == 4 && a[1] == 9 && a[3] == 12 && f[0] == 2 && f[1] == 4 && f[2] == 60
3290 && f[3] == 8 && f[4] == 10 {
3291 println('A')
3292 } else {
3293 println('a')
3294 }
3295}
3296"
3297}
3298
3299fn x64_fixed_array_slice_copy_stdout() []u8 {
3300 return 'SCA
3301'.bytes()
3302}
3303
3304fn x64_dynamic_int_array_source() string {
3305 return "module main
3306
3307fn main() {
3308 mut a := [1, 2, 3]
3309 if a.len == 3 && a[0] == 1 && a[2] == 3 {
3310 print('L')
3311 } else {
3312 print('l')
3313 }
3314 a[1] = 7
3315 a << 11
3316 if a.len == 4 && a[1] == 7 && a[3] == 11 {
3317 print('P')
3318 } else {
3319 print('p')
3320 }
3321 mut i := 0
3322 mut sum := 0
3323 for i < a.len {
3324 sum += a[i]
3325 i += 1
3326 }
3327 if sum == 22 {
3328 println('S')
3329 } else {
3330 println('s')
3331 }
3332}
3333"
3334}
3335
3336fn x64_dynamic_int_array_stdout() []u8 {
3337 return 'LPS
3338'.bytes()
3339}
3340
3341fn x64_dynamic_string_array_index_source() string {
3342 return "module main
3343
3344fn main() {
3345 mut values := []string{}
3346 values << 'alpha'
3347 values << 'beta'
3348 println(values[1])
3349}
3350"
3351}
3352
3353fn x64_dynamic_string_array_index_stdout() []u8 {
3354 return 'beta
3355'.bytes()
3356}
3357
3358fn x64_dynamic_string_array_str_source() string {
3359 return "module main
3360
3361fn main() {
3362 path := ['A', 'C', 'F']
3363 println(path)
3364 println('path: \${path}')
3365 mut values := []string{}
3366 values << 'alpha'
3367 values << 'beta'
3368 println(values)
3369 graph := {
3370 'A': ['B', 'C']
3371 }
3372 println(graph)
3373 fixed := ['L', 'R']!
3374 println(fixed)
3375}
3376"
3377}
3378
3379fn x64_dynamic_string_array_str_stdout() []u8 {
3380 return "['A', 'C', 'F']
3381path: ['A', 'C', 'F']
3382['alpha', 'beta']
3383{'A': ['B', 'C']}
3384['L', 'R']
3385".bytes()
3386}
3387
3388fn x64_mut_array_param_append_source() string {
3389 return "module main
3390
3391fn append_seen(mut seen []string) {
3392 seen << 'A'
3393 seen << 'B'
3394}
3395
3396fn append_many(mut seen []string, values []string) {
3397 seen << values
3398}
3399
3400fn append_path(mut path []string) {
3401 path << 'A'
3402 path << 'B'
3403}
3404
3405fn append_pattern_value(mut patterns [][]string, path []string) {
3406 patterns << path
3407}
3408
3409fn append_pattern_literal(mut patterns [][]string, path []string) {
3410 patterns << [path]
3411}
3412
3413fn main() {
3414 mut seen := []string{}
3415 append_seen(mut seen)
3416 println(seen)
3417 println(seen.reverse())
3418 mut many := []string{}
3419 append_many(mut many, ['B', 'A'])
3420 println(many)
3421 mut path := []string{}
3422 append_path(mut path)
3423 println(path)
3424 mut value_patterns := [][]string{}
3425 append_pattern_value(mut value_patterns, path)
3426 println(value_patterns)
3427 mut literal_patterns := [][]string{}
3428 append_pattern_literal(mut literal_patterns, path)
3429 println(literal_patterns)
3430}
3431"
3432}
3433
3434fn x64_mut_array_param_append_stdout() []u8 {
3435 return "['A', 'B']
3436['B', 'A']
3437['B', 'A']
3438['A', 'B']
3439[['A', 'B']]
3440[['A', 'B']]
3441".bytes()
3442}
3443
3444fn x64_string_int_map_literal_lookup_source() string {
3445 return "module main
3446
3447fn main() {
3448 values := {
3449 'A': 11
3450 'B': 22
3451 }
3452 println(values['A'])
3453 println(values['B'])
3454}
3455"
3456}
3457
3458fn x64_string_int_map_literal_lookup_stdout() []u8 {
3459 return '11
346022
3461'.bytes()
3462}
3463
3464fn x64_map_clone_delete_array_index_delete_source() string {
3465 return "module main
3466
3467fn main() {
3468 graph := {
3469 'A': ['B', 'C']
3470 'B': ['C']
3471 'C': []
3472 }
3473 mut next := graph.clone()
3474 next.delete('B')
3475 mut path := graph['A'].clone()
3476 idx := path.index('B')
3477 if idx >= 0 {
3478 path.delete(idx)
3479 }
3480 println('\${graph.len}:\${next.len}:\${'B' in graph}:\${'B' in next}')
3481 println('\${idx}:\${path.len}:\${path.index('B')}:\${path[0]}')
3482 mut degree := map[string]int{}
3483 degree['A'] = 0
3484 degree['C'] = 1
3485 first := degree.keys().first()
3486 println('\${'A' in degree}:\${'B' in degree}:\${first in degree}:\${degree['C']}')
3487}
3488"
3489}
3490
3491fn x64_map_clone_delete_array_index_delete_stdout() []u8 {
3492 return '3:2:true:false
34930:1:-1:C
3494true:false:true:1
3495'.bytes()
3496}
3497
3498fn x64_graph_priority_queue_generic_mut_array_source() string {
3499 return "module main
3500
3501struct Node {
3502mut:
3503 data int
3504 priority int
3505}
3506
3507fn push_pq[T](mut queue []T, data int, priority int) {
3508 mut temp := []T{}
3509 mut i := 0
3510 for i < queue.len && priority > queue[i].priority {
3511 temp << queue[i]
3512 i++
3513 }
3514 temp << Node{data, priority}
3515 for i < queue.len {
3516 temp << queue[i]
3517 i++
3518 }
3519 queue = temp.clone()
3520}
3521
3522fn update_priority[T](mut queue []T, search int, priority int) {
3523 for i in 0 .. queue.len {
3524 if queue[i].data == search {
3525 queue[i] = Node{search, priority}
3526 break
3527 }
3528 }
3529}
3530
3531fn pop_front[T](mut queue []T) int {
3532 value := queue[0].data
3533 queue.delete(0)
3534 return value
3535}
3536
3537fn all_adjacents[T](g [][]T, v int) []int {
3538 mut out := []int{}
3539 for i in 0 .. g.len {
3540 if g[v][i] > 0 {
3541 out << i
3542 }
3543 }
3544 return out
3545}
3546
3547fn main() {
3548 mut queue := []Node{}
3549 push_pq(mut queue, 7, 20)
3550 push_pq(mut queue, 4, 10)
3551 push_pq(mut queue, 9, 30)
3552 update_priority(mut queue, 7, 15)
3553 graph := [
3554 [0, 5, 0],
3555 [5, 0, 8],
3556 [0, 8, 0],
3557 ]
3558 println('\${pop_front(mut queue)}|\${queue[0].data}:\${queue[0].priority}|\${all_adjacents(graph, 1)}')
3559}
3560"
3561}
3562
3563fn x64_graph_priority_queue_generic_mut_array_stdout() []u8 {
3564 return '4|7:15|[0, 2]
3565'.bytes()
3566}
3567
3568fn x64_graph_generic_map_edge_relax_source() string {
3569 return "module main
3570
3571const large = 999
3572
3573struct Edge {
3574mut:
3575 src int
3576 dest int
3577 weight int
3578}
3579
3580fn build_edges[T](g [][]T) map[T]Edge {
3581 n := g.len
3582 mut edges := map[int]Edge{}
3583 mut edge := 0
3584 for i in 0 .. n {
3585 for j in 0 .. n {
3586 if g[i][j] != 0 {
3587 edges[edge] = Edge{i, j, g[i][j]}
3588 edge++
3589 }
3590 }
3591 }
3592 return edges
3593}
3594
3595fn relax[T](graph [][]T) []int {
3596 mut edges := build_edges[int](graph)
3597 n_edges := edges.len
3598 mut dist := []int{len: graph.len, init: large}
3599 dist[0] = 0
3600 for _ in 0 .. graph.len {
3601 for j in 0 .. n_edges {
3602 u := edges[j].src
3603 v := edges[j].dest
3604 weight := edges[j].weight
3605 if dist[u] != large && dist[u] + weight < dist[v] {
3606 dist[v] = dist[u] + weight
3607 }
3608 }
3609 }
3610 return dist
3611}
3612
3613fn main() {
3614 graph := [
3615 [0, 3, 10],
3616 [0, 0, -2],
3617 [0, 0, 0],
3618 ]
3619 dist := relax(graph)
3620 println('\${dist[0]},\${dist[1]},\${dist[2]}')
3621}
3622"
3623}
3624
3625fn x64_graph_generic_map_edge_relax_stdout() []u8 {
3626 return '0,3,1
3627'.bytes()
3628}
3629
3630fn x64_windows_noscan_array_grow_free_slice_source() string {
3631 return "module main
3632
3633fn make_array() []int {
3634 return [1, 2, 3]
3635}
3636
3637fn main() {
3638 mut a := make_array()
3639 if a.len == 3 && a.cap >= 3 && a[0] == 1 && a[2] == 3 {
3640 print('N')
3641 } else {
3642 print('n')
3643 }
3644 a << 4
3645 if a.len == 4 && a[1] == 2 && a[3] == 4 {
3646 print('G')
3647 } else {
3648 print('g')
3649 }
3650 b := a[1..3]
3651 if b.len == 2 && b[0] == 2 && b[1] == 3 {
3652 print('S')
3653 } else {
3654 print('s')
3655 }
3656 unsafe {
3657 a.free()
3658 }
3659 println('F')
3660}
3661"
3662}
3663
3664fn x64_windows_noscan_array_grow_free_slice_stdout() []u8 {
3665 return 'NGSF
3666'.bytes()
3667}
3668
3669fn x64_windows_rune_array_string_free_source() string {
3670 return "module main
3671
3672fn main() {
3673 mut runes := []rune{cap: 5}
3674 runes << rune(79)
3675 runes << 75
3676 mut s := runes.string()
3677 if s.len == 2 && s == 'OK' {
3678 print('R')
3679 } else {
3680 print('r')
3681 }
3682 print(s)
3683 unsafe {
3684 s.free()
3685 }
3686 println('F')
3687}
3688"
3689}
3690
3691fn x64_windows_rune_array_string_free_stdout() []u8 {
3692 return 'ROKF
3693'.bytes()
3694}
3695
3696fn x64_fizz_buzz_core_source() string {
3697 return "module main
3698
3699fn main() {
3700 for n in 1 .. 16 {
3701 value := match true {
3702 n % 15 == 0 { 'FizzBuzz' }
3703 n % 5 == 0 { 'Buzz' }
3704 n % 3 == 0 { 'Fizz' }
3705 else { n.str() }
3706 }
3707 println(value)
3708 }
3709}
3710"
3711}
3712
3713fn x64_fizz_buzz_core_stdout() []u8 {
3714 return '1
37152
3716Fizz
37174
3718Buzz
3719Fizz
37207
37218
3722Fizz
3723Buzz
372411
3725Fizz
372613
372714
3728FizzBuzz
3729'.bytes()
3730}
3731
3732fn x64_named_function_value_source() string {
3733 return 'module main
3734
3735fn inc(value int) int {
3736 return value + 1
3737}
3738
3739fn apply(f fn (int) int, value int) int {
3740 return f(value)
3741}
3742
3743fn main() {
3744 f := inc
3745 println(f(10))
3746 println(apply(inc, 20))
3747}
3748'
3749}
3750
3751fn x64_named_function_value_stdout() []u8 {
3752 return '11
375321
3754'.bytes()
3755}
3756
3757fn x64_selective_import_builtin_shadow_fn_value_sources() map[string]string {
3758 return {
3759 'main.v': 'module main
3760
3761import mymodules { print }
3762
3763fn main() {
3764 f := print
3765 f("ok")
3766}
3767'
3768 'mymodules/main_functions.v': 'module mymodules
3769
3770pub fn print(s string) {
3771 println("module:" + s)
3772}
3773'
3774 }
3775}
3776
3777fn x64_selective_import_builtin_shadow_fn_value_stdout() []u8 {
3778 return 'module:ok
3779'.bytes()
3780}
3781
3782fn x64_selective_import_bare_fallback_shadow_sources() map[string]string {
3783 return {
3784 'main.v': 'module main
3785
3786import mymodules { malloc }
3787
3788fn main() {
3789 f := malloc
3790 println(f("fn-value"))
3791 println(malloc("direct"))
3792}
3793'
3794 'mymodules/main_functions.v': 'module mymodules
3795
3796pub fn malloc(s string) string {
3797 return "module:" + s
3798}
3799'
3800 }
3801}
3802
3803fn x64_selective_import_bare_fallback_shadow_stdout() []u8 {
3804 return 'module:fn-value
3805module:direct
3806'.bytes()
3807}
3808
3809fn x64_selective_import_method_shadow_sources() map[string]string {
3810 return {
3811 'main.v': 'module main
3812
3813import mymodules { ping }
3814
3815struct Foo {}
3816
3817fn (f Foo) ping() string {
3818 return "method"
3819}
3820
3821fn main() {
3822 println(ping())
3823}
3824'
3825 'mymodules/main_functions.v': 'module mymodules
3826
3827pub fn ping() string {
3828 return "module"
3829}
3830'
3831 }
3832}
3833
3834fn x64_selective_import_method_shadow_stdout() []u8 {
3835 return 'module
3836'.bytes()
3837}
3838
3839fn x64_non_capturing_fn_literal_value_source() string {
3840 return 'module main
3841
3842fn apply(f fn (int) int, value int) int {
3843 return f(value)
3844}
3845
3846fn main() {
3847 f := fn (value int) int {
3848 return value + 7
3849 }
3850 println(f(7))
3851 println(apply(fn (value int) int {
3852 return value + 3
3853 }, 8))
3854}
3855'
3856}
3857
3858fn x64_non_capturing_fn_literal_value_stdout() []u8 {
3859 return '14
386011
3861'.bytes()
3862}
3863
3864fn x64_returned_non_capturing_fn_literal_source() string {
3865 return 'module main
3866
3867fn make_double() fn (int) int {
3868 return fn (value int) int {
3869 return value * 2
3870 }
3871}
3872
3873fn apply(f fn (int) int, value int) int {
3874 return f(value)
3875}
3876
3877fn main() {
3878 f := make_double()
3879 println(f(9))
3880 println(apply(make_double(), 12))
3881}
3882'
3883}
3884
3885fn x64_returned_non_capturing_fn_literal_stdout() []u8 {
3886 return '18
388724
3888'.bytes()
3889}
3890
3891fn x64_examples_dir() string {
3892 return os.join_path(@VMODROOT, 'examples')
3893}
3894
3895fn x64_get_raw_line_example_stdin() string {
3896 return 'hello\nworld\n'
3897}
3898
3899fn x64_get_raw_line_example_stdout() []u8 {
3900 return 'Press Ctrl+D(Linux) or Ctrl+Z(Windows) at line begin to exit\n1: hello\n\n2: world\n\n'.bytes()
3901}
3902
3903fn x64_mini_calculator_example_stdin() string {
3904 return '3+4*2\nexit\n'
3905}
3906
3907fn x64_mini_calculator_example_stdout() []u8 {
3908 return "Please enter the expression you want to calculate, e.g. 1e2+(3-2.5)*6/1.5 .\nEnter 'exit' or 'EXIT' to quit.\n[1] 11.0\n[2] ".bytes()
3909}
3910
3911fn x64_mini_calculator_recursive_descent_example_stdout() []u8 {
3912 return 'Enter expressions to calculate, e.g. `2 * (5-1)` or `exit` to quit.
3913[1] 11.0
3914[2] '.bytes()
3915}
3916
3917fn x64_arguments_index_one_int_source() string {
3918 return 'module main
3919
3920fn main() {
3921 args := arguments()
3922 println(args.len)
3923 println(args[1].int() + 32)
3924}
3925'
3926}
3927
3928fn x64_arguments_index_one_int_stdout() []u8 {
3929 return '2
393042
3931'.bytes()
3932}
3933
3934fn x64_arguments_via_function_pointer_source() string {
3935 return 'module main
3936
3937fn get_args_len() int {
3938 return arguments().len
3939}
3940
3941fn call_it(f fn () int) int {
3942 return f()
3943}
3944
3945fn main() {
3946 f := get_args_len
3947 println(call_it(f))
3948}
3949'
3950}
3951
3952fn x64_arguments_via_function_pointer_stdout() []u8 {
3953 return '2
3954'.bytes()
3955}
3956
3957fn x64_math_log_20_source() string {
3958 return 'module main
3959
3960import math { log }
3961
3962fn main() {
3963 x := log(20.0)
3964 println(x > 2.99 && x < 3.0)
3965}
3966'
3967}
3968
3969fn x64_math_log_20_stdout() []u8 {
3970 return 'true
3971'.bytes()
3972}
3973
3974fn x64_embedded_scanner_parser_source() string {
3975 return "module main
3976
3977import strings.textscanner
3978
3979struct Parser {
3980 textscanner.TextScanner
3981}
3982
3983fn main() {
3984 mut parser := Parser{textscanner.new('3+4*2')}
3985 if parser.input == '3+4*2' {
3986 println('input')
3987 }
3988 if parser.ilen == 5 {
3989 println('ilen')
3990 }
3991 if parser.pos == 0 {
3992 println('pos0')
3993 }
3994 if parser.peek_u8() == `3` {
3995 println('peek3')
3996 }
3997 first := parser.next()
3998 if first == `3` {
3999 println('next3')
4000 }
4001 if parser.pos == 1 {
4002 println('pos1')
4003 }
4004 if parser.peek_u8() == `+` {
4005 println('peek_plus')
4006 }
4007 start := 0
4008 for parser.peek_u8().is_digit() {
4009 parser.next()
4010 }
4011 token := parser.input[start..parser.pos]
4012 if token == '3' {
4013 println('slice')
4014 }
4015}
4016"
4017}
4018
4019fn x64_embedded_scanner_parser_stdout() []u8 {
4020 return 'input
4021ilen
4022pos0
4023peek3
4024next3
4025pos1
4026peek_plus
4027slice
4028'.bytes()
4029}
4030
4031fn x64_struct_positional_side_effect_source() string {
4032 return "module main
4033
4034struct Sample {
4035 x int
4036}
4037
4038fn next() int {
4039 println('call')
4040 return 7
4041}
4042
4043fn main() {
4044 sample := Sample{next()}
4045 println(sample.x)
4046}
4047"
4048}
4049
4050fn x64_struct_positional_side_effect_stdout() []u8 {
4051 return 'call
40527
4053'.bytes()
4054}
4055
4056fn x64_struct_named_side_effect_source() string {
4057 return "module main
4058
4059struct Sample {
4060 x int
4061 y int
4062}
4063
4064fn next() int {
4065 println('call')
4066 return 7
4067}
4068
4069fn main() {
4070 sample := Sample{
4071 x: next()
4072 y: 2
4073 }
4074 println(sample.x)
4075 println(sample.y)
4076}
4077"
4078}
4079
4080fn x64_struct_named_side_effect_stdout() []u8 {
4081 return 'call
40827
40832
4084'.bytes()
4085}
4086
4087fn x64_unrelated_same_shape_struct_source() string {
4088 return 'module main
4089
4090struct SameShape {
4091 x int
4092 y int
4093}
4094
4095struct Holder {
4096 item SameShape
4097 z int
4098}
4099
4100fn main() {
4101 holder := Holder{SameShape{7, 9}, 2}
4102 println(holder.item.x)
4103 println(holder.item.y)
4104 println(holder.z)
4105}
4106'
4107}
4108
4109fn x64_unrelated_same_shape_struct_stdout() []u8 {
4110 return '7
41119
41122
4113'.bytes()
4114}
4115
4116fn x64_named_init_embedded_value_source() string {
4117 return 'module main
4118
4119struct Inner {
4120 x int
4121}
4122
4123struct Holder {
4124 Inner
4125 other Inner
4126}
4127
4128fn main() {
4129 holder := Holder{
4130 other: Inner{7}
4131 }
4132 println(holder.x)
4133 println(holder.other.x)
4134}
4135'
4136}
4137
4138fn x64_named_init_embedded_value_stdout() []u8 {
4139 return '0
41407
4141'.bytes()
4142}
4143
4144fn x64_hello_world_example_stdout() []u8 {
4145 return 'Hello, World!\n'.bytes()
4146}
4147
4148fn x64_fibonacci_10_example_stdout() []u8 {
4149 return '1
41501
41512
41523
41535
41548
415513
415621
415734
415855
415989
4160'.bytes()
4161}
4162
4163fn x64_submodule_example_stdout() []u8 {
4164 return '5
41653
4166'.bytes()
4167}
4168
4169fn x64_fizz_buzz_example_stdout() []u8 {
4170 return '1
41712
4172Fizz
41734
4174Buzz
4175Fizz
41767
41778
4178Fizz
4179Buzz
418011
4181Fizz
418213
418314
4184FizzBuzz
418516
418617
4187Fizz
418819
4189Buzz
4190Fizz
419122
419223
4193Fizz
4194Buzz
419526
4196Fizz
419728
419829
4199FizzBuzz
420031
420132
4202Fizz
420334
4204Buzz
4205Fizz
420637
420738
4208Fizz
4209Buzz
421041
4211Fizz
421243
421344
4214FizzBuzz
421546
421647
4217Fizz
421849
4219Buzz
4220Fizz
422152
422253
4223Fizz
4224Buzz
422556
4226Fizz
422758
422859
4229FizzBuzz
423061
423162
4232Fizz
423364
4234Buzz
4235Fizz
423667
423768
4238Fizz
4239Buzz
424071
4241Fizz
424273
424374
4244FizzBuzz
424576
424677
4247Fizz
424879
4249Buzz
4250Fizz
425182
425283
4253Fizz
4254Buzz
425586
4256Fizz
425788
425889
4259FizzBuzz
426091
426192
4262Fizz
426394
4264Buzz
4265Fizz
426697
426798
4268Fizz
4269Buzz
4270'.bytes()
4271}
4272
4273fn x64_hanoi_example_stdout() []u8 {
4274 mut out := []u8{}
4275 x64_hanoi_example_append_expected(mut out, 7, 'A', 'B', 'C')
4276 text := out.bytestr()
4277 move_count := text.count('\n')
4278 assert out.len == 2794, 'hanoi stdout oracle source shape changed: bytes=${out.len}'
4279 assert move_count == 127, 'hanoi stdout oracle source shape changed: moves=${move_count}'
4280 assert text.starts_with('Disc 1 from A to C...\nDisc 2 from A to B...\n'), 'hanoi stdout oracle first moves changed'
4281 assert text.ends_with('Disc 2 from B to C...\nDisc 1 from A to C...\n'), 'hanoi stdout oracle final moves changed'
4282 return out
4283}
4284
4285fn x64_hanoi_example_append_expected(mut out []u8, n int, a string, b string, c string) {
4286 if n == 1 {
4287 out << 'Disc 1 from ${a} to ${c}...\n'.bytes()
4288 return
4289 }
4290 x64_hanoi_example_append_expected(mut out, n - 1, a, c, b)
4291 out << 'Disc ${n} from ${a} to ${c}...\n'.bytes()
4292 x64_hanoi_example_append_expected(mut out, n - 1, b, a, c)
4293}
4294
4295fn x64_sudoku_example_stdout() []u8 {
4296 mut out := []u8{}
4297 x64_sudoku_append_stdout_line(mut out, 'Sudoku Puzzle:', false)
4298 x64_sudoku_append_stdout_line(mut out, '0 3 0 | 0 7 0 | 0 0 0', true)
4299 x64_sudoku_append_stdout_line(mut out, '0 0 0 | 1 3 5 | 0 0 0', true)
4300 x64_sudoku_append_stdout_line(mut out, '0 0 1 | 0 0 0 | 0 5 0', true)
4301 x64_sudoku_append_stdout_line(mut out, '- - - - - - - - - - - -', false)
4302 x64_sudoku_append_stdout_line(mut out, '1 0 0 | 0 6 0 | 0 0 3', true)
4303 x64_sudoku_append_stdout_line(mut out, '4 0 0 | 8 0 3 | 0 0 1', true)
4304 x64_sudoku_append_stdout_line(mut out, '7 0 0 | 0 2 0 | 0 0 6', true)
4305 x64_sudoku_append_stdout_line(mut out, '- - - - - - - - - - - -', false)
4306 x64_sudoku_append_stdout_line(mut out, '0 0 0 | 0 0 0 | 2 1 0', true)
4307 x64_sudoku_append_stdout_line(mut out, '0 0 0 | 4 1 2 | 0 0 5', true)
4308 x64_sudoku_append_stdout_line(mut out, '0 0 0 | 0 0 0 | 0 7 4', true)
4309 x64_sudoku_append_stdout_line(mut out, 'Solving...', false)
4310 x64_sudoku_append_stdout_line(mut out, 'Solution:', false)
4311 x64_sudoku_append_stdout_line(mut out, '2 3 5 | 6 7 8 | 1 4 9', true)
4312 x64_sudoku_append_stdout_line(mut out, '9 4 7 | 1 3 5 | 8 6 2', true)
4313 x64_sudoku_append_stdout_line(mut out, '6 8 1 | 2 4 9 | 3 5 7', true)
4314 x64_sudoku_append_stdout_line(mut out, '- - - - - - - - - - - -', false)
4315 x64_sudoku_append_stdout_line(mut out, '1 2 8 | 7 6 4 | 5 9 3', true)
4316 x64_sudoku_append_stdout_line(mut out, '4 5 6 | 8 9 3 | 7 2 1', true)
4317 x64_sudoku_append_stdout_line(mut out, '7 9 3 | 5 2 1 | 4 8 6', true)
4318 x64_sudoku_append_stdout_line(mut out, '- - - - - - - - - - - -', false)
4319 x64_sudoku_append_stdout_line(mut out, '3 6 4 | 9 5 7 | 2 1 8', true)
4320 x64_sudoku_append_stdout_line(mut out, '8 7 9 | 4 1 2 | 6 3 5', true)
4321 x64_sudoku_append_stdout_line(mut out, '5 1 2 | 3 8 6 | 9 7 4', true)
4322 return out
4323}
4324
4325fn x64_sudoku_append_stdout_line(mut out []u8, line string, trailing_space bool) {
4326 out << line.bytes()
4327 if trailing_space {
4328 out << u8(` `)
4329 }
4330 out << u8(`\n`)
4331}
4332
4333fn x64_function_types_example_stdout() []u8 {
4334 return 'HELLO WORLD
4335HELLO WORLD
4336HELLO WORLD
4337'.bytes()
4338}
4339
4340fn x64_struct_sumtype_field_init_source() string {
4341 return '
4342module main
4343
4344type Tree = Empty | Node
4345
4346struct Empty {}
4347
4348struct Node {
4349 value int
4350}
4351
4352struct Holder {
4353 item Tree
4354}
4355
4356fn value(tree Tree) int {
4357 return match tree {
4358 Empty { 0 }
4359 Node { tree.value }
4360 }
4361}
4362
4363fn main() {
4364 holder := Holder{Node{42}}
4365 println(value(holder.item))
4366}
4367'
4368}
4369
4370fn x64_struct_sumtype_field_init_stdout() []u8 {
4371 return '42
4372'.bytes()
4373}
4374
4375fn x64_auto_str_recursive_sumtype_source() string {
4376 return '
4377module main
4378
4379type Tree = Empty | Node
4380
4381struct Empty {}
4382
4383struct Node {
4384 value int
4385 left Tree
4386 right Tree
4387}
4388
4389fn main() {
4390 leaf := Node{7, Empty{}, Empty{}}
4391 root := Node{9, leaf, Empty{}}
4392 print("\${root}")
4393}
4394'
4395}
4396
4397fn x64_auto_str_recursive_sumtype_stdout() []u8 {
4398 return 'Node{
4399 value: 9
4400 left: Tree(Node{
4401 value: 7
4402 left: Tree(Empty{})
4403 right: Tree(Empty{})
4404 })
4405 right: Tree(Empty{})
4406}'.bytes()
4407}
4408
4409fn x64_tree_of_nodes_example_stdout() []u8 {
4410 return 'tree structure:
4411 Node{
4412 value: 10
4413 left: Tree(Node{
4414 value: 30
4415 left: Tree(Empty{})
4416 right: Tree(Empty{})
4417 })
4418 right: Tree(Node{
4419 value: 20
4420 left: Tree(Empty{})
4421 right: Tree(Empty{})
4422 })
4423}
4424tree size: 3
4425'.bytes()
4426}
4427
4428fn x64_bfs_example_stdout() []u8 {
4429 return "Graph: {'A': ['B', 'C'], 'B': ['A', 'D', 'E'], 'C': ['A', 'F'], 'D': ['B'], 'E': ['B', 'F'], 'F': ['C', 'E']}
4430The shortest path from node A to node F is: ['A', 'C', 'F']
4431".bytes()
4432}
4433
4434fn x64_minimal_spann_tree_prim_example_stdout() []u8 {
4435 return '
4436 Minimal Spanning Tree of graph 1 using PRIM algorithm
4437 Edge Weight
4438
4439 0 <== reference or start node
4440 1 <--> 0 4
4441 2 <--> 8 2
4442 3 <--> 2 7
4443 4 <--> 5 10
4444 5 <--> 6 2
4445 6 <--> 7 1
4446 7 <--> 6 1
4447 8 <--> 2 2
4448 Minimum Cost Spanning Tree: 29
4449
4450
4451 Minimal Spanning Tree of graph 2 using PRIM algorithm
4452 Edge Weight
4453
4454 0 <== reference or start node
4455 1 <--> 0 2
4456 2 <--> 1 3
4457 3 <--> 0 6
4458 4 <--> 1 5
4459 Minimum Cost Spanning Tree: 16
4460
4461
4462 Minimal Spanning Tree of graph 3 using PRIM algorithm
4463 Edge Weight
4464
4465 0 <== reference or start node
4466 1 <--> 0 10
4467 2 <--> 0 6
4468 3 <--> 0 5
4469 Minimum Cost Spanning Tree: 21
4470
4471
4472 BYE -- OK
4473'.bytes()
4474}
4475
4476fn x64_bellman_ford_example_stdout() []u8 {
4477 return '
4478
4479 Graph 1 using Bellman-Ford algorithm (source node: 0)
4480
4481 Vertex Distance from Source
4482 0 --> 0
4483 1 --> -1
4484 2 --> 2
4485 3 --> -2
4486 4 --> 1
4487
4488 Graph 2 using Bellman-Ford algorithm (source node: 0)
4489
4490 Vertex Distance from Source
4491 0 --> 0
4492 1 --> 2
4493 2 --> 5
4494 3 --> 6
4495 4 --> 7
4496
4497 Graph 3 using Bellman-Ford algorithm (source node: 0)
4498
4499 Vertex Distance from Source
4500 0 --> 0
4501 1 --> 10
4502 2 --> 6
4503 3 --> 5
4504 BYE -- OK
4505'.bytes()
4506}
4507
4508fn x64_js_hello_world_example_stdout() []u8 {
4509 return 'Hello from V.js (0)
4510Hello from V.js (1)
4511Hello from V.js (2)
4512'.bytes()
4513}
4514
4515fn x64_vascii_example_stdout() []u8 {
4516 source := os.read_file(os.join_path(x64_examples_dir(), 'vascii.v')) or { panic(err) }
4517 start_marker := "println('"
4518 end_marker := "')"
4519 assert source.count(start_marker) == 1, 'vascii stdout oracle expects one single-quoted println literal'
4520 start := source.index(start_marker) or { panic('missing vascii println literal start') } +
4521 start_marker.len
4522 end := source.last_index(end_marker) or { panic('missing vascii println literal end') }
4523 assert source[end + end_marker.len..].trim_space() == '}', 'vascii stdout oracle expects the println literal to be the final main statement'
4524
4525 mut out := x64_v_single_quoted_literal_bytes(source[start..end])
4526 assert out.len == 8525, 'vascii stdout oracle source shape changed: literal bytes=${out.len}'
4527 assert out.bytestr().contains('DEC OCT HEX BIN Sym'), 'vascii stdout oracle missing table header'
4528
4529 assert out.bytestr().contains('127 177 7F 01111111 DEL  Delete'), 'vascii stdout oracle missing final ASCII row'
4530
4531 out << u8(`\n`)
4532 return out
4533}
4534
4535fn x64_v_single_quoted_literal_bytes(raw string) []u8 {
4536 mut out := []u8{cap: raw.len}
4537 mut i := 0
4538 for i < raw.len {
4539 if raw[i] == `\\` && i + 1 < raw.len {
4540 match raw[i + 1] {
4541 `n` { out << u8(`\n`) }
4542 `t` { out << u8(`\t`) }
4543 `r` { out << u8(`\r`) }
4544 `\\` { out << u8(`\\`) }
4545 `'` { out << u8(`'`) }
4546 `"` { out << u8(`"`) }
4547 else { out << raw[i + 1] }
4548 }
4549
4550 i += 2
4551 continue
4552 }
4553 out << raw[i]
4554 i++
4555 }
4556 return out
4557}
4558
4559fn x64_rune_example_stdout() []u8 {
4560 return [u8(0xf0), 0x9f, 0x98, 0x80, u8(`\n`), u8(`@`), u8(`\n`)]
4561}
4562
4563fn x64_rune_utf32_parity_stdout() []u8 {
4564 return [
4565 u8(0x7f),
4566 u8(`\n`),
4567 u8(0xc2),
4568 0x80,
4569 u8(`\n`),
4570 u8(0xdf),
4571 0xbf,
4572 u8(`\n`),
4573 u8(0xe0),
4574 0xa0,
4575 0x80,
4576 u8(`\n`),
4577 u8(0xed),
4578 0x9f,
4579 0xbf,
4580 u8(`\n`),
4581 u8(0xed),
4582 0xa0,
4583 0x80,
4584 u8(`\n`),
4585 u8(0xed),
4586 0xbf,
4587 0xbf,
4588 u8(`\n`),
4589 u8(0xee),
4590 0x80,
4591 0x80,
4592 u8(`\n`),
4593 u8(0xef),
4594 0xbf,
4595 0xbf,
4596 u8(`\n`),
4597 u8(0xf0),
4598 0x90,
4599 0x80,
4600 0x80,
4601 u8(`\n`),
4602 u8(0xf4),
4603 0x8f,
4604 0xbf,
4605 0xbf,
4606 u8(`\n`),
4607 u8(`\n`),
4608 ]
4609}
4610
4611fn x64_long_ascii_literal_stdout() []u8 {
4612 mut out := []u8{cap: 600}
4613 for i in 0 .. 600 {
4614 out << u8(`A` + i % 26)
4615 }
4616 return out
4617}
4618
4619fn x64_repeated_ascii_literal(ch u8, count int) string {
4620 mut out := []u8{cap: count}
4621 for _ in 0 .. count {
4622 out << ch
4623 }
4624 return out.bytestr()
4625}
4626
4627fn x64_long_ascii_literal_source() string {
4628 literal := x64_long_ascii_literal_stdout().bytestr()
4629 return "module main
4630
4631fn emit(s string) {
4632 print(s)
4633}
4634
4635fn main() {
4636 emit('${literal}')
4637}
4638 "
4639}
4640
4641fn x64_string_literal_field_size_source() string {
4642 literal := x64_long_ascii_literal_stdout().bytestr()
4643 return "module main
4644
4645struct BoxedString {
4646 before u8
4647 value string
4648 after u8
4649}
4650
4651fn emit(s string) {
4652 println(s.len)
4653 println(s.is_lit)
4654}
4655
4656fn main() {
4657 s := '${literal}'
4658 boxed := BoxedString{
4659 before: 17
4660 value: s
4661 after: 23
4662 }
4663 println(s.len)
4664 println(s.is_lit)
4665 println(boxed.value.len)
4666 println(boxed.value.is_lit)
4667 println(int(boxed.before))
4668 println(int(boxed.after))
4669 emit('${literal}')
4670}
4671"
4672}
4673