🐛 Refresh wasm heap views after allocations and wasm calls (#12833)

Growing the heap detaches typed views taken before an alloc or a call.
Take them after, so reads and writes never hit a detached buffer.
This commit is contained in:
Elena Torró 2026-11-05 18:09:59 +01:00 committed by GitHub
parent a32f5a9811
commit afc40a3309
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 46 additions and 48 deletions

View File

@ -74,9 +74,7 @@
;; to its default dash pattern when no override is stored.
dash (or (:stroke-dash stroke) -1)
gap (or (:stroke-gap stroke) -1)
offset (mem/alloc types.fills.impl/FILL-U8-SIZE)
heap (mem/get-heap-u8)
dview (js/DataView. (.-buffer heap))]
offset (mem/alloc types.fills.impl/FILL-U8-SIZE)]
(case align
:inner (h/call wasm/internal-module "_add_shape_inner_stroke" width style cap-start cap-end dash gap)
:outer (h/call wasm/internal-module "_add_shape_outer_stroke" width style cap-start cap-end dash gap)
@ -94,17 +92,17 @@
(cond
(some? gradient)
(do (types.fills.impl/write-gradient-fill offset dview opacity gradient)
(do (types.fills.impl/write-gradient-fill offset (mem/get-data-view) opacity gradient)
(h/call wasm/internal-module "_add_shape_stroke_fill")
nil)
(some? image)
(do (types.fills.impl/write-image-fill offset dview opacity image)
(do (types.fills.impl/write-image-fill offset (mem/get-data-view) opacity image)
(h/call wasm/internal-module "_add_shape_stroke_fill")
(get image :id))
(some? color)
(do (types.fills.impl/write-solid-fill offset dview opacity color)
(do (types.fills.impl/write-solid-fill offset (mem/get-data-view) opacity color)
(h/call wasm/internal-module "_add_shape_stroke_fill")
nil))))))
strokes))
@ -179,15 +177,14 @@
buffer (js/Uint8Array. padded-size)]
(path/write-to content (.-buffer buffer) 0)
(h/call wasm/internal-module "_start_shape_path_buffer")
(let [heapu32 (mem/get-heap-u32)]
(loop [offset 0]
(when (< offset padded-size)
(let [end (min padded-size (+ offset (* chunk-size 4)))
chunk (.subarray buffer offset end)
chunk-u32 (js/Uint32Array. chunk.buffer chunk.byteOffset (quot (.-length chunk) 4))
offset-size (.-length chunk-u32)
heap-offset (mem/alloc->offset-32 (* 4 offset-size))]
(.set heapu32 chunk-u32 heap-offset)
(h/call wasm/internal-module "_set_shape_path_chunk_buffer")
(recur end)))))
(loop [offset 0]
(when (< offset padded-size)
(let [end (min padded-size (+ offset (* chunk-size 4)))
chunk (.subarray buffer offset end)
chunk-u32 (js/Uint32Array. chunk.buffer chunk.byteOffset (quot (.-length chunk) 4))
offset-size (.-length chunk-u32)
heap-offset (mem/alloc->offset-32 (* 4 offset-size))]
(.set (mem/get-heap-u32) chunk-u32 heap-offset)
(h/call wasm/internal-module "_set_shape_path_chunk_buffer")
(recur end))))
(h/call wasm/internal-module "_set_shape_path_buffer")))

View File

@ -190,9 +190,9 @@
text-buffer (encode-text text)
text-size (mem/size text-buffer)
total-size (+ 4 metadata-size text-size)
offset (mem/alloc total-size)
heapu8 (mem/get-heap-u8)
dview (mem/get-data-view)
offset (mem/alloc total-size)]
dview (mem/get-data-view)]
(-> offset
(mem/write-u32 dview num-spans)
(write-paragraph dview paragraph)

View File

@ -858,9 +858,9 @@
(let [children (into [] (filter uuid?) children)]
(if (empty? children)
(h/call wasm/internal-module "_set_children_0")
(let [heap (mem/get-heap-u32)
size (mem/get-alloc-size children UUID-U8-SIZE)
offset (mem/alloc->offset-32 size)]
(let [size (mem/get-alloc-size children UUID-U8-SIZE)
offset (mem/alloc->offset-32 size)
heap (mem/get-heap-u32)]
(reduce
(fn [offset id]
(mem.h32/write-uuid offset heap id))
@ -2060,8 +2060,8 @@
[entries]
(when (and (initialized?) (not ^boolean (empty? entries)))
(let [size (mem/get-alloc-size entries UUID-U8-SIZE)
heap (mem/get-heap-u32)
offset (mem/alloc->offset-32 size)]
offset (mem/alloc->offset-32 size)
heap (mem/get-heap-u32)]
(reduce (fn [offset id]
(mem.h32/write-uuid offset heap id))
@ -2084,8 +2084,8 @@
(when (and (initialized?) (seq shape-ids))
(let [ids (vec shape-ids)
size (mem/get-alloc-size ids UUID-U8-SIZE)
heap (mem/get-heap-u32)
offset (mem/alloc->offset-32 size)]
offset (mem/alloc->offset-32 size)
heap (mem/get-heap-u32)]
(reduce (fn [offset id]
(mem.h32/write-uuid offset heap id))
offset
@ -2143,10 +2143,10 @@
[entries snap-pixel? snap-ignore-axis]
(if-not (and (initialized?) (not ^boolean (empty? entries)))
[]
(let [heapf32 (mem/get-heap-f32)
heapu32 (mem/get-heap-u32)
size (mem/get-alloc-size entries INPUT-MODIFIER-U8-SIZE)
offset (mem/alloc->offset-32 size)]
(let [size (mem/get-alloc-size entries INPUT-MODIFIER-U8-SIZE)
offset (mem/alloc->offset-32 size)
heapf32 (mem/get-heap-f32)
heapu32 (mem/get-heap-u32)]
(reduce (fn [offset [id data]]
(let [transform (:transform data)
@ -2161,6 +2161,8 @@
(let [precision (pixel-precision-mode snap-pixel? snap-ignore-axis)
offset (-> (h/call wasm/internal-module "_propagate_modifiers" precision)
(mem/->offset-32))
heapf32 (mem/get-heap-f32)
heapu32 (mem/get-heap-u32)
length (aget heapu32 offset)
max-offset (+ offset 1 (* length MODIFIER-U32-SIZE))
result (loop [result (transient [])
@ -2180,8 +2182,7 @@
(when (and (initialized?) (not ^boolean (empty? entries)))
(let [size (mem/get-alloc-size entries UUID-U8-SIZE)
offset (mem/alloc->offset-32 size)
heapu32 (mem/get-heap-u32)
heapf32 (mem/get-heap-f32)]
heapu32 (mem/get-heap-u32)]
(reduce (fn [offset id]
(mem.h32/write-uuid offset heapu32 id))
@ -2190,7 +2191,7 @@
(let [offset (-> (h/call wasm/internal-module "_get_selection_rect")
(mem/->offset-32))
result (dr/read-selection-rect heapf32 offset)]
result (dr/read-selection-rect (mem/get-heap-f32) offset)]
(mem/free)
result))))
@ -2759,8 +2760,8 @@
(defn calculate-bool*
[bool-type ids]
(let [size (mem/get-alloc-size ids UUID-U8-SIZE)
heap (mem/get-heap-u32)
offset (mem/alloc->offset-32 size)]
offset (mem/alloc->offset-32 size)
heap (mem/get-heap-u32)]
(reduce (fn [offset id]
(mem.h32/write-uuid offset heap id))
@ -2772,6 +2773,7 @@
(-> (h/call wasm/internal-module "_calculate_bool" (sr/translate-bool-type bool-type))
(mem/->offset-32))
heap (mem/get-heap-u32)
length (aget heap offset)
data (mem/slice heap
(+ offset 1)
@ -2827,10 +2829,10 @@
[shape]
(when (initialized?)
(wselect/use-shape (:id shape))
(let [heapf32 (mem/get-heap-f32)
heapu32 (mem/get-heap-u32)
offset (-> (h/call wasm/internal-module "_calculate_position_data")
(let [offset (-> (h/call wasm/internal-module "_calculate_position_data")
(mem/->offset-32))
heapf32 (mem/get-heap-f32)
heapu32 (mem/get-heap-u32)
length (aget heapu32 offset)
max-offset (+ offset 1 (* length POSITION-DATA-U32-SIZE))
@ -3001,8 +3003,8 @@
(when (and (initialized?) (seq shape-ids))
(let [ids (vec shape-ids)
size (mem/get-alloc-size ids UUID-U8-SIZE)
heap (mem/get-heap-u32)
offset (mem/alloc->offset-32 size)
heap (mem/get-heap-u32)
_ (reduce (fn [offset id]
(mem.h32/write-uuid offset heap id))
@ -3080,8 +3082,8 @@
(when (and (initialized?) (seq shape-ids))
(let [ids (vec shape-ids)
size (mem/get-alloc-size ids UUID-U8-SIZE)
heap (mem/get-heap-u32)
offset (mem/alloc->offset-32 size)
heap (mem/get-heap-u32)
_ (reduce (fn [offset id]
(mem.h32/write-uuid offset heap id))

View File

@ -383,10 +383,9 @@
(wasm/ready?))
(let [encoder (js/TextEncoder.)
buf (.encode encoder text)
heapu8 (mem/get-heap-u8)
size (mem/size buf)
offset (mem/alloc size)]
(mem/write-buffer offset heapu8 buf))))
(mem/write-buffer offset (mem/get-heap-u8) buf))))
(defn text-editor-encode-text-post
[text]
@ -506,10 +505,10 @@
(when (wasm/ready?)
(try
(let [byte-offset (mem/alloc 16)
u32-offset (mem/->offset-32 byte-offset)
heap (mem/get-heap-u32)]
u32-offset (mem/->offset-32 byte-offset)]
(h/call wasm/internal-module "_text_editor_get_active_shape_id" byte-offset)
(let [a (aget heap u32-offset)
(let [heap (mem/get-heap-u32)
a (aget heap u32-offset)
b (aget heap (+ u32-offset 1))
c (aget heap (+ u32-offset 2))
d (aget heap (+ u32-offset 3))
@ -526,10 +525,10 @@
(when (wasm/ready?)
(let [byte-offset (mem/alloc 16)
u32-offset (mem/->offset-32 byte-offset)
heap (mem/get-heap-u32)
has-selection? (h/call wasm/internal-module "_text_editor_get_selection" byte-offset)]
(if has-selection?
(let [result {:anchor-para (aget heap u32-offset)
(let [heap (mem/get-heap-u32)
result {:anchor-para (aget heap u32-offset)
:anchor-offset (aget heap (+ u32-offset 1))
:focus-para (aget heap (+ u32-offset 2))
:focus-offset (aget heap (+ u32-offset 3))}]
@ -870,10 +869,10 @@
(let [id (uuid/get-u32 shape-id)
byte-offset (mem/alloc 16)
f32-offset (mem/->offset-32 byte-offset)
heap (mem/get-heap-f32)
has-text? (h/call wasm/internal-module "_text_get_range_origin"
(aget id 0) (aget id 1) (aget id 2) (aget id 3)
start-para start-offset end-para end-offset byte-offset)
heap (mem/get-heap-f32)
result (when has-text?
{:x (aget heap f32-offset)
:y (aget heap (+ f32-offset 1))