nandi/vflutter_ffipublic Fork 0
81540bbed5044d569fccbcb6c081878d54bbbd5b
Commits
Clone
git clone https://git.rickub.com/nandi/vflutter_ffi.git
git clone ssh://git@rickub.com/nandi/vflutter_ffi.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

vflutter.v · 117 lines · 3.3 KBCoq Blame HistoryRaw
Initial commit: V -> Flutter FFI plugin ad0ccda nandi 9h ago1module main
2
Add a Mandelbrot example app, and a V kernel worth demonstrating 81540bb nandithebull 5h ago3import math
4
Initial commit: V -> Flutter FFI plugin ad0ccda nandi 9h ago5// ---------------------------------------------------------------------------
6// C-ABI surface consumed by Dart FFI.
7//
8// Rules for everything below:
9// * only C-compatible types cross the boundary (int, f64, &char, voidptr)
10// * V strings/arrays/options/sumtypes never cross; convert first
11// * anything V allocates and hands out is released by vf_free
12// ---------------------------------------------------------------------------
13
14// Touches the V runtime so the GC and global initialisers are demonstrably
15// live. The ELF/Mach-O constructor emitted by `v -shared` already does this;
16// this exists for static-archive builds (iOS) where the caller wants a
17// guaranteed, idempotent entry point.
18@[export: 'vf_init']
19fn vf_init() {
20 probe := 'vf'
21 _ = probe.len
22}
23
24@[export: 'vf_add']
25fn vf_add(a int, b int) int {
26 return a + b
27}
28
29// Returns a V-allocated C string. Caller releases it with vf_free.
30//
31// Built with `-gc none`, so every intermediate V allocation here must be
32// freed by hand. Only the returned buffer outlives the call.
33@[export: 'vf_greet']
34fn vf_greet(name &char) &char {
35 n := unsafe { cstring_to_vstring(name) }
36 res := 'Hello, ${n}, from V!'
37 out := unsafe { res.str }
38 unsafe { n.free() }
39 return out
40}
41
42@[export: 'vf_free']
43fn vf_free(p voidptr) {
44 unsafe { free(p) }
45}
Add a Mandelbrot example app, and a V kernel worth demonstrating 81540bb nandithebull 5h ago46
47// ---------------------------------------------------------------------------
48// Mandelbrot kernel.
49//
50// The buffer is allocated and owned by the *caller*: V only fills it. That
51// sidesteps the -gc none ownership rules entirely for bulk data there is
52// nothing to vf_free, and no allocation happens inside the hot loop.
53//
54// Rows [y0, y1) of a w x h image are written as RGBA8888, packed from the
55// start of `buf`, so each call fills a self-contained horizontal band and
56// several bands can be computed concurrently from different isolates.
57// ---------------------------------------------------------------------------
58@[export: 'vf_mandelbrot']
59fn vf_mandelbrot(buf &u8, w int, h int, cx f64, cy f64, scale f64, max_iter int, y0 int, y1 int) {
60 if w <= 0 || h <= 0 || max_iter <= 0 {
61 return
62 }
63 aspect := f64(w) / f64(h)
64 inv_w := 1.0 / f64(w)
65 inv_h := 1.0 / f64(h)
66
67 for y := y0; y < y1; y++ {
68 im := cy + (f64(y) * inv_h - 0.5) * scale
69 row := (y - y0) * w * 4
70 for x := 0; x < w; x++ {
71 re := cx + (f64(x) * inv_w - 0.5) * scale * aspect
72
73 mut zr := 0.0
74 mut zi := 0.0
75 mut zr2 := 0.0
76 mut zi2 := 0.0
77 mut i := 0
78 for i < max_iter {
79 zr2 = zr * zr
80 zi2 = zi * zi
81 if zr2 + zi2 > 4.0 {
82 break
83 }
84 zi = 2.0 * zr * zi + im
85 zr = zr2 - zi2 + re
86 i++
87 }
88
89 idx := row + x * 4
90 if i >= max_iter {
91 // Inside the set.
92 unsafe {
93 buf[idx] = u8(0)
94 buf[idx + 1] = u8(0)
95 buf[idx + 2] = u8(0)
96 buf[idx + 3] = u8(255)
97 }
98 continue
99 }
100
101 // Smooth (fractional) escape count, so bands don't posterise.
102 mag := math.sqrt(zr2 + zi2)
103 mut nu := f64(i)
104 if mag > 1.0 {
105 nu = f64(i) + 1.0 - math.log(math.log(mag) / math.log(2.0)) / math.log(2.0)
106 }
107 t := nu / f64(max_iter)
108
109 unsafe {
110 buf[idx] = u8(255.0 * (0.5 + 0.5 * math.sin(3.0 + t * 18.0)))
111 buf[idx + 1] = u8(255.0 * (0.5 + 0.5 * math.sin(3.6 + t * 18.0)))
112 buf[idx + 2] = u8(255.0 * (0.5 + 0.5 * math.sin(4.2 + t * 18.0)))
113 buf[idx + 3] = u8(255)
114 }
115 }
116 }
117}