Skip to content

Commit e78b731

Browse files
authored
v2: implement native x64 backend, part 2 (#27365)
1 parent a715332 commit e78b731

36 files changed

Lines changed: 10850 additions & 523 deletions

.github/workflows/linux_ci.yml

Lines changed: 188 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ jobs:
100100
run: |
101101
set -e
102102
103-
./v test vlib/v2/abi vlib/v2/gen/x64
103+
VJOBS=1 ./v test vlib/v2/abi vlib/v2/gen/x64
104+
./v test vlib/v2/builder/native_test.v vlib/v2/builder/target_os_test.v
104105
./v test vlib/v2/ssa/optimize
105106
V2_VERIFY_STRICT=1 ./v test vlib/v2/ssa/optimize
106107
@@ -131,6 +132,26 @@ jobs:
131132
fi
132133
}
133134
135+
run_native_x64_example() {
136+
source="$1"
137+
name="$2"
138+
expected="$3"
139+
shift 3
140+
141+
./v -v2 -no-parallel -b x64 "$source" -o "$tmp/$name"
142+
"$tmp/$name" "$@" > "$tmp/$name.out" 2> "$tmp/$name.err"
143+
check_empty_stderr "$name" "$tmp/$name.err"
144+
check_stdout "$name" "$expected" "$tmp/$name.out"
145+
}
146+
147+
write_v_run_expected() {
148+
source="$1"
149+
expected="$2"
150+
stderr="$tmp/$(basename "$expected").stderr"
151+
./v run "$source" > "$expected" 2> "$stderr"
152+
check_empty_stderr "v run $source" "$stderr"
153+
}
154+
134155
write_fizz_buzz_expected() {
135156
i=1
136157
while [ "$i" -le 100 ]; do
@@ -147,17 +168,174 @@ jobs:
147168
done
148169
}
149170
150-
./v -v2 -b x64 examples/hello_world.v -o "$tmp/hello_world"
151-
"$tmp/hello_world" > "$tmp/hello_world.out" 2> "$tmp/hello_world.err"
152-
printf 'Hello, World!\n' > "$tmp/hello_world.expected"
153-
check_empty_stderr hello_world "$tmp/hello_world.err"
154-
check_stdout hello_world "$tmp/hello_world.expected" "$tmp/hello_world.out"
171+
write_hanoi_expected() {
172+
python3 - <<'PY'
173+
def hanoi(n, a, b, c):
174+
if n == 1:
175+
print(f"Disc 1 from {a} to {c}...")
176+
else:
177+
hanoi(n - 1, a, c, b)
178+
print(f"Disc {n} from {a} to {c}...")
179+
hanoi(n - 1, b, a, c)
180+
181+
hanoi(7, "A", "B", "C")
182+
PY
183+
}
184+
185+
write_sudoku_expected() {
186+
python3 - <<'PY'
187+
import sys
188+
189+
puzzle = [
190+
[0, 3, 0, 0, 7, 0, 0, 0, 0],
191+
[0, 0, 0, 1, 3, 5, 0, 0, 0],
192+
[0, 0, 1, 0, 0, 0, 0, 5, 0],
193+
[1, 0, 0, 0, 6, 0, 0, 0, 3],
194+
[4, 0, 0, 8, 0, 3, 0, 0, 1],
195+
[7, 0, 0, 0, 2, 0, 0, 0, 6],
196+
[0, 0, 0, 0, 0, 0, 2, 1, 0],
197+
[0, 0, 0, 4, 1, 2, 0, 0, 5],
198+
[0, 0, 0, 0, 0, 0, 0, 7, 4],
199+
]
200+
solution = [
201+
[2, 3, 5, 6, 7, 8, 1, 4, 9],
202+
[9, 4, 7, 1, 3, 5, 8, 6, 2],
203+
[6, 8, 1, 2, 4, 9, 3, 5, 7],
204+
[1, 2, 8, 7, 6, 4, 5, 9, 3],
205+
[4, 5, 6, 8, 9, 3, 7, 2, 1],
206+
[7, 9, 3, 5, 2, 1, 4, 8, 6],
207+
[3, 6, 4, 9, 5, 7, 2, 1, 8],
208+
[8, 7, 9, 4, 1, 2, 6, 3, 5],
209+
[5, 1, 2, 3, 8, 6, 9, 7, 4],
210+
]
211+
212+
def append_grid(lines, label, grid):
213+
lines.append(label)
214+
for i, row in enumerate(grid):
215+
if i % 3 == 0 and i != 0:
216+
lines.append("- - - - - - - - - - - -")
217+
line = ""
218+
for j, value in enumerate(row):
219+
if j % 3 == 0 and j != 0:
220+
line += " | "
221+
line += f"{value} "
222+
lines.append(line)
223+
224+
lines = []
225+
append_grid(lines, "Sudoku Puzzle:", puzzle)
226+
lines.append("Solving...")
227+
append_grid(lines, "Solution:", solution)
228+
out = ("\n".join(lines) + "\n").encode()
229+
if len(out) != 582:
230+
raise SystemExit(f"sudoku stdout oracle shape changed: {len(out)} bytes")
231+
sys.stdout.buffer.write(out)
232+
PY
233+
}
155234
156-
./v -v2 -b x64 examples/fizz_buzz.v -o "$tmp/fizz_buzz"
157-
"$tmp/fizz_buzz" > "$tmp/fizz_buzz.out" 2> "$tmp/fizz_buzz.err"
235+
write_tree_of_nodes_expected() {
236+
cat <<'EOF'
237+
tree structure:
238+
Node{
239+
value: 10
240+
left: Tree(Node{
241+
value: 30
242+
left: Tree(Empty{})
243+
right: Tree(Empty{})
244+
})
245+
right: Tree(Node{
246+
value: 20
247+
left: Tree(Empty{})
248+
right: Tree(Empty{})
249+
})
250+
}
251+
tree size: 3
252+
EOF
253+
}
254+
255+
write_js_hello_world_expected() {
256+
printf 'Hello from V.js (0)\nHello from V.js (1)\nHello from V.js (2)\n'
257+
}
258+
259+
write_vascii_expected() {
260+
python3 - <<'PY'
261+
from pathlib import Path
262+
import sys
263+
264+
source = Path("examples/vascii.v").read_text(encoding="utf-8")
265+
start_marker = "println('"
266+
end_marker = "')"
267+
if source.count(start_marker) != 1:
268+
raise SystemExit("vascii stdout oracle expects one single-quoted println literal")
269+
start = source.index(start_marker) + len(start_marker)
270+
end = source.rindex(end_marker)
271+
if source[end + len(end_marker):].strip() != "}":
272+
raise SystemExit("vascii stdout oracle expects the println literal to be the final main statement")
273+
274+
out = bytearray()
275+
literal = source[start:end]
276+
i = 0
277+
while i < len(literal):
278+
ch = literal[i]
279+
if ch == "\\":
280+
i += 1
281+
if i >= len(literal):
282+
raise SystemExit("unterminated escape in vascii literal")
283+
escaped = literal[i]
284+
if escaped == "n":
285+
out.append(10)
286+
elif escaped == "t":
287+
out.append(9)
288+
elif escaped == "r":
289+
out.append(13)
290+
elif escaped == "\\":
291+
out.append(92)
292+
elif escaped == "'":
293+
out.append(39)
294+
elif escaped == '"':
295+
out.append(34)
296+
else:
297+
out.extend(escaped.encode("utf-8"))
298+
else:
299+
out.extend(ch.encode("utf-8"))
300+
i += 1
301+
out.append(10)
302+
sys.stdout.buffer.write(out)
303+
PY
304+
}
305+
306+
write_rune_expected() {
307+
printf '\360\237\230\200\n@\n'
308+
}
309+
310+
printf 'Hello, World!\n' > "$tmp/hello_world.expected"
158311
write_fizz_buzz_expected > "$tmp/fizz_buzz.expected"
159-
check_empty_stderr fizz_buzz "$tmp/fizz_buzz.err"
160-
check_stdout fizz_buzz "$tmp/fizz_buzz.expected" "$tmp/fizz_buzz.out"
312+
write_hanoi_expected > "$tmp/hanoi.expected"
313+
write_sudoku_expected > "$tmp/sudoku.expected"
314+
printf 'HELLO WORLD\nHELLO WORLD\nHELLO WORLD\n' > "$tmp/function_types.expected"
315+
printf '5\n3\n' > "$tmp/submodule.expected"
316+
printf '1\n1\n2\n3\n5\n8\n13\n21\n34\n55\n89\n' > "$tmp/fibonacci_10.expected"
317+
write_tree_of_nodes_expected > "$tmp/tree_of_nodes.expected"
318+
write_js_hello_world_expected > "$tmp/js_hello_world.expected"
319+
write_vascii_expected > "$tmp/vascii.expected"
320+
write_rune_expected > "$tmp/rune.expected"
321+
write_v_run_expected examples/graphs/bfs.v "$tmp/bfs.expected"
322+
write_v_run_expected examples/graphs/dfs.v "$tmp/dfs.expected"
323+
write_v_run_expected examples/graphs/dijkstra.v "$tmp/dijkstra.expected"
324+
325+
run_native_x64_example examples/hello_world.v hello_world "$tmp/hello_world.expected"
326+
run_native_x64_example examples/fizz_buzz.v fizz_buzz "$tmp/fizz_buzz.expected"
327+
run_native_x64_example examples/hanoi.v hanoi "$tmp/hanoi.expected"
328+
run_native_x64_example examples/sudoku.v sudoku "$tmp/sudoku.expected"
329+
run_native_x64_example examples/function_types.v function_types "$tmp/function_types.expected"
330+
run_native_x64_example examples/submodule/main.v submodule "$tmp/submodule.expected"
331+
run_native_x64_example examples/fibonacci.v fibonacci "$tmp/fibonacci_10.expected" 10
332+
run_native_x64_example examples/tree_of_nodes.v tree_of_nodes "$tmp/tree_of_nodes.expected"
333+
run_native_x64_example examples/js_hello_world.v js_hello_world "$tmp/js_hello_world.expected"
334+
run_native_x64_example examples/vascii.v vascii "$tmp/vascii.expected"
335+
run_native_x64_example examples/rune.v rune "$tmp/rune.expected"
336+
run_native_x64_example examples/graphs/bfs.v bfs "$tmp/bfs.expected"
337+
run_native_x64_example examples/graphs/dfs.v dfs "$tmp/dfs.expected"
338+
run_native_x64_example examples/graphs/dijkstra.v dijkstra "$tmp/dijkstra.expected"
161339
- name: All code is formatted
162340
run: v run ci/linux_ci.vsh all_code_is_formatted_gcc
163341
- name: Install dependencies for examples and tools

0 commit comments

Comments
 (0)