Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: sample SIGSEGV — free() cast to wrong callback signature

Root cause: JS_NewArrayBuffer's free callback takes 3 args
(JSRuntime *rt, void *opaque, void *ptr) but we cast plain free()
which takes 1 arg. When QuickJS GC'd the ArrayBuffer, it called
free(rt_pointer) instead of free(data_pointer) — instant SIGSEGV.

Fix: proper js_free_array_buffer wrapper that ignores rt/opaque
and calls free(ptr).

This bug existed since getData() was first written and crashed
100% of the time when the returned Float32Array was GC'd.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

+7 -1
+7 -1
fedac/native/src/js-bindings.c
··· 1206 1206 } 1207 1207 1208 1208 // sound.sample.getData() — returns Float32Array of current sample buffer 1209 + // Proper free callback for JS_NewArrayBuffer (3-arg signature, not plain free) 1210 + static void js_free_array_buffer(JSRuntime *rt, void *opaque, void *ptr) { 1211 + (void)rt; (void)opaque; 1212 + free(ptr); 1213 + } 1214 + 1209 1215 static JSValue js_sample_get_data(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { 1210 1216 (void)this_val; (void)argc; (void)argv; 1211 1217 ACAudio *audio = current_rt ? current_rt->audio : NULL; ··· 1225 1231 1226 1232 // Create ArrayBuffer from our copy 1227 1233 JSValue ab = JS_NewArrayBuffer(ctx, (uint8_t *)copy, byte_len, 1228 - (JSFreeArrayBufferDataFunc *)free, NULL, 0); 1234 + js_free_array_buffer, NULL, 0); 1229 1235 if (JS_IsException(ab)) { free(copy); return JS_UNDEFINED; } 1230 1236 1231 1237 // Create Float32Array view