safer typed array finalizer

This commit is contained in:
Fabrice Bellard 2023-12-22 11:03:13 +01:00
parent a96f440746
commit 1692f2a7a3

View file

@ -51090,11 +51090,26 @@ static void js_array_buffer_finalizer(JSRuntime *rt, JSValue val)
{ {
JSObject *p = JS_VALUE_GET_OBJ(val); JSObject *p = JS_VALUE_GET_OBJ(val);
JSArrayBuffer *abuf = p->u.array_buffer; JSArrayBuffer *abuf = p->u.array_buffer;
struct list_head *el, *el1;
if (abuf) { if (abuf) {
/* The ArrayBuffer finalizer may be called before the typed /* The ArrayBuffer finalizer may be called before the typed
array finalizers using it, so abuf->array_list is not array finalizers using it, so abuf->array_list is not
necessarily empty. */ necessarily empty. */
// assert(list_empty(&abuf->array_list)); list_for_each_safe(el, el1, &abuf->array_list) {
JSTypedArray *ta;
JSObject *p1;
ta = list_entry(el, JSTypedArray, link);
ta->link.prev = NULL;
ta->link.next = NULL;
p1 = ta->obj;
/* Note: the typed array length and offset fields are not modified */
if (p1->class_id != JS_CLASS_DATAVIEW) {
p1->u.array.count = 0;
p1->u.array.u.ptr = NULL;
}
}
if (abuf->shared && rt->sab_funcs.sab_free) { if (abuf->shared && rt->sab_funcs.sab_free) {
rt->sab_funcs.sab_free(rt->sab_funcs.sab_opaque, abuf->data); rt->sab_funcs.sab_free(rt->sab_funcs.sab_opaque, abuf->data);
} else { } else {
@ -53030,7 +53045,7 @@ static void js_typed_array_finalizer(JSRuntime *rt, JSValue val)
if (ta) { if (ta) {
/* during the GC the finalizers are called in an arbitrary /* during the GC the finalizers are called in an arbitrary
order so the ArrayBuffer finalizer may have been called */ order so the ArrayBuffer finalizer may have been called */
if (JS_IsLiveObject(rt, JS_MKPTR(JS_TAG_OBJECT, ta->buffer))) { if (ta->link.next) {
list_del(&ta->link); list_del(&ta->link);
} }
JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_OBJECT, ta->buffer)); JS_FreeValueRT(rt, JS_MKPTR(JS_TAG_OBJECT, ta->buffer));