feat(lang): L7 memory is safe unless it says unsafe
The typed buffers are slices: words/floats/fixeds/doubles/pointers(n) make
zeroed, bounds-checked []int/[]float/... and the type names mean them. buffer(n)
is a []byte, with text_of, Fs.read_bytes/write_bytes and view(xs, start, n).
bytes(), indexing a raw pointer or bytes, free, resize, Memory.*, raw file calls,
data_of and C externs are refused outside unsafe { } / unsafe function, and a
project's own files may write unsafe only with --unsafe; the runtime and packages
are the platform. A slice passed to an extern goes as its data.
What the change found: Sync's atomics on a slice header, words(n) uninitialised,
input's fixed axes in ints, truetype's fixed outlines as ints, skin matrices
typed int, gl_shader's source table made from raw bytes. render3d gets safe
entry points (safe_api.ludic). Rendering is byte-identical; a frame costs the same.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
9259808f80
commit
b0b0b62bce
70 changed files with 69189 additions and 64569 deletions
|
|
@ -116,7 +116,7 @@ function model_cross_card() -> Model {
|
|||
let idx = words(12)
|
||||
idx[0] = 0; idx[1] = 1; idx[2] = 2; idx[3] = 0; idx[4] = 2; idx[5] = 3
|
||||
idx[6] = 4; idx[7] = 5; idx[8] = 6; idx[9] = 4; idx[10] = 6; idx[11] = 7
|
||||
gpu_mesh_indices(m, idx, 48, 4)
|
||||
gpu_mesh_indices(m, data_of(idx), 48, 4)
|
||||
free(idx)
|
||||
m.count = 12
|
||||
gpu_mesh_done(m)
|
||||
|
|
@ -194,7 +194,7 @@ function model_lupine() -> Model {
|
|||
gpu_mesh_vertices(m, v, gl_bytes_of(nq * 4 * 8), GPU_STATIC)
|
||||
sc_model_layout(m)
|
||||
free(v)
|
||||
gpu_mesh_indices(m, idx, nq * 6 * 4, 4)
|
||||
gpu_mesh_indices(m, data_of(idx), nq * 6 * 4, 4)
|
||||
free(idx)
|
||||
m.count = nq * 6
|
||||
gpu_mesh_done(m)
|
||||
|
|
@ -267,7 +267,7 @@ function model_lupine_dense() -> Model {
|
|||
gpu_mesh_vertices(m, v, gl_bytes_of(nq * 4 * 8), GPU_STATIC)
|
||||
sc_model_layout(m)
|
||||
free(v)
|
||||
gpu_mesh_indices(m, idx, nq * 6 * 4, 4)
|
||||
gpu_mesh_indices(m, data_of(idx), nq * 6 * 4, 4)
|
||||
free(idx)
|
||||
m.count = nq * 6
|
||||
gpu_mesh_done(m)
|
||||
|
|
@ -315,7 +315,7 @@ function model_blade() -> Model {
|
|||
idx[k + 3] = a + 1; idx[k + 4] = a + 3; idx[k + 5] = a + 2
|
||||
k += 6
|
||||
}
|
||||
gpu_mesh_indices(m, idx, ni * 4, 4)
|
||||
gpu_mesh_indices(m, data_of(idx), ni * 4, 4)
|
||||
free(idx)
|
||||
m.count = ni
|
||||
gpu_mesh_done(m)
|
||||
|
|
@ -667,7 +667,7 @@ function layer_gpu_prepare(l: Layer) -> bool {
|
|||
}
|
||||
let n = l.n_lods
|
||||
let cap = l.count
|
||||
gpu_buffer_upload(l.g_src, cap * INST_FLOATS * 4, l.inst, GPU_STATIC)
|
||||
gpu_buffer_upload(l.g_src, cap * INST_FLOATS * 4, data_of(l.inst), GPU_STATIC)
|
||||
gpu_buffer_upload(l.g_dst, (n + 1) * cap * INST_FLOATS * 4, null, GPU_DYNAMIC)
|
||||
if l.g_arena == null { layer_arena_build(l) }
|
||||
let n_mat = len(l.g_arena)
|
||||
|
|
@ -690,14 +690,14 @@ function layer_gpu_prepare(l: Layer) -> bool {
|
|||
}
|
||||
}
|
||||
}
|
||||
gpu_buffer_upload(l.g_cmds, SC_RECS * SC_REC_W, rec, GPU_DYNAMIC)
|
||||
gpu_buffer_upload(l.g_cmds, SC_RECS * SC_REC_W, data_of(rec), GPU_DYNAMIC)
|
||||
let zeros = words(5)
|
||||
for i in 0 .. 5 { zeros[i] = 0 }
|
||||
gpu_buffer_upload(l.g_counts, 20, zeros, GPU_DYNAMIC)
|
||||
gpu_buffer_upload(l.g_counts, 20, data_of(zeros), GPU_DYNAMIC)
|
||||
free(rec); free(zeros)
|
||||
# the card casts every instance, as on the CPU path (layer_grid_build uploads this there)
|
||||
l.n_sh = l.count
|
||||
gpu_buffer_upload(l.sh_buf, l.count * INST_FLOATS * 4, l.inst, GPU_STATIC)
|
||||
gpu_buffer_upload(l.sh_buf, l.count * INST_FLOATS * 4, data_of(l.inst), GPU_STATIC)
|
||||
l.g_n = l.count
|
||||
l.g_on = true
|
||||
return true
|
||||
|
|
@ -715,7 +715,7 @@ function layer_gpu_cull(l: Layer) -> void {
|
|||
pr[32] = float_bits(l.lods[0].height * 2.0); pr[33] = float_bits(4.0)
|
||||
let bufs = words(4)
|
||||
bufs[0] = l.g_src; bufs[1] = l.g_dst; bufs[2] = l.g_cmds; bufs[3] = l.g_counts
|
||||
gpu_dispatch(sc_cull_prog, pr, 144, bufs, 1)
|
||||
gpu_dispatch(sc_cull_prog, data_of(pr), 144, bufs, 1)
|
||||
free(pr); free(bufs)
|
||||
}
|
||||
|
||||
|
|
@ -762,7 +762,7 @@ function layer_grid_build(l: Layer, cell: float) -> void {
|
|||
free(cellof); free(fill)
|
||||
if l.vis == null { l.vis = floats(l.cap * INST_FLOATS) }
|
||||
l.n_sh = l.count
|
||||
gpu_buffer_upload(l.sh_buf, l.count * INST_FLOATS * 4, l.inst, GPU_STATIC)
|
||||
gpu_buffer_upload(l.sh_buf, l.count * INST_FLOATS * 4, data_of(l.inst), GPU_STATIC)
|
||||
}
|
||||
|
||||
# gather the instances of the cells the camera can see (and that are within cull)
|
||||
|
|
@ -848,7 +848,7 @@ function layer_partition_lods(l: Layer, src: floats, total: int) -> void {
|
|||
# casters: the whole (gathered) set from the shadow buffer, unless the impostor casts
|
||||
if l.gcell == 0.0 {
|
||||
l.n_sh = total
|
||||
if total > 0 { gpu_buffer_upload(l.sh_buf, total * INST_FLOATS * 4, src, GPU_DYNAMIC) }
|
||||
if total > 0 { gpu_buffer_upload(l.sh_buf, total * INST_FLOATS * 4, data_of(src), GPU_DYNAMIC) }
|
||||
}
|
||||
free(counts); free(start); free(fill)
|
||||
}
|
||||
|
|
@ -866,7 +866,7 @@ function layer_update(l: Layer) -> void {
|
|||
# per-instance loop — one upload, and the same buffer casts its shadows.
|
||||
if l.streamed and l.imp == null and l.near == 0.0 and l.n_lods <= 1 {
|
||||
l.n_near = l.count; l.n_far = 0; l.n_sh = l.count
|
||||
gpu_buffer_upload(l.buf, l.count * INST_FLOATS * 4, l.inst, GPU_DYNAMIC)
|
||||
gpu_buffer_upload(l.buf, l.count * INST_FLOATS * 4, data_of(l.inst), GPU_DYNAMIC)
|
||||
prof_layer_add(gl_now_us() - t_lu, l.count * INST_FLOATS * 4)
|
||||
return
|
||||
}
|
||||
|
|
@ -916,10 +916,10 @@ function layer_update(l: Layer) -> void {
|
|||
if l.gcell == 0.0 {
|
||||
l.n_sh = l.count
|
||||
if l.count > 0 {
|
||||
gpu_buffer_upload(l.sh_buf, l.count * INST_FLOATS * 4, l.inst, GPU_DYNAMIC)
|
||||
gpu_buffer_upload(l.sh_buf, l.count * INST_FLOATS * 4, data_of(l.inst), GPU_DYNAMIC)
|
||||
}
|
||||
}
|
||||
gpu_buffer_upload(l.buf, nn * INST_FLOATS * 4, tmp, GPU_DYNAMIC)
|
||||
gpu_buffer_upload(l.buf, nn * INST_FLOATS * 4, data_of(tmp), GPU_DYNAMIC)
|
||||
if nf > 0 {
|
||||
gpu_buffer_upload(l.imp_buf, nf * INST_FLOATS * 4, mem_off(tmp, (far_off - nf * INST_FLOATS) * 4), GPU_DYNAMIC)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue