Introduce JS_ReadObject2

Analogously to JS_WriteObject2, it allows the user to get a tab with all
the SAB objects that were read.

This can help adjust reference counts in a scenario where a SAB that was
written increased it and it's necessary to decrease it upon reading it.
This commit is contained in:
Saúl Ibarra Corretgé 2024-07-15 09:22:43 +02:00
parent c011898ea0
commit 3ed591c02d
2 changed files with 25 additions and 3 deletions

View file

@ -33995,7 +33995,10 @@ typedef struct BCReaderState {
JSObject **objects; JSObject **objects;
int objects_count; int objects_count;
int objects_size; int objects_size;
/* SAB references */
uint8_t **sab_tab;
int sab_tab_len;
int sab_tab_size;
/* used for DUMP_READ_OBJECT */ /* used for DUMP_READ_OBJECT */
const uint8_t *ptr_last; const uint8_t *ptr_last;
int level; int level;
@ -34903,6 +34906,11 @@ static JSValue JS_ReadSharedArrayBuffer(BCReaderState *s)
if (bc_get_u64(s, &u64)) if (bc_get_u64(s, &u64))
return JS_EXCEPTION; return JS_EXCEPTION;
data_ptr = (uint8_t *)(uintptr_t)u64; data_ptr = (uint8_t *)(uintptr_t)u64;
if (js_resize_array(s->ctx, (void **)&s->sab_tab, sizeof(s->sab_tab[0]),
&s->sab_tab_size, s->sab_tab_len + 1))
return JS_EXCEPTION;
/* keep the SAB pointer so that the user can clone it or free it */
s->sab_tab[s->sab_tab_len++] = data_ptr;
/* the SharedArrayBuffer is cloned */ /* the SharedArrayBuffer is cloned */
obj = js_array_buffer_constructor3(ctx, JS_UNDEFINED, byte_length, obj = js_array_buffer_constructor3(ctx, JS_UNDEFINED, byte_length,
JS_CLASS_SHARED_ARRAY_BUFFER, JS_CLASS_SHARED_ARRAY_BUFFER,
@ -35156,8 +35164,8 @@ static void bc_reader_free(BCReaderState *s)
js_free(s->ctx, s->objects); js_free(s->ctx, s->objects);
} }
JSValue JS_ReadObject(JSContext *ctx, const uint8_t *buf, size_t buf_len, JSValue JS_ReadObject2(JSContext *ctx, const uint8_t *buf, size_t buf_len,
int flags) int flags, uint8_t ***psab_tab, size_t *psab_tab_len)
{ {
BCReaderState ss, *s = &ss; BCReaderState ss, *s = &ss;
JSValue obj; JSValue obj;
@ -35182,10 +35190,22 @@ JSValue JS_ReadObject(JSContext *ctx, const uint8_t *buf, size_t buf_len,
} else { } else {
obj = JS_ReadObjectRec(s); obj = JS_ReadObjectRec(s);
} }
if (psab_tab)
*psab_tab = s->sab_tab;
else
js_free(ctx, s->sab_tab);
if (psab_tab_len)
*psab_tab_len = s->sab_tab_len;
bc_reader_free(s); bc_reader_free(s);
return obj; return obj;
} }
JSValue JS_ReadObject(JSContext *ctx, const uint8_t *buf, size_t buf_len,
int flags)
{
return JS_ReadObject2(ctx, buf, buf_len, flags, NULL, NULL);
}
/*******************************************************************/ /*******************************************************************/
/* runtime functions & objects */ /* runtime functions & objects */

View file

@ -856,6 +856,8 @@ JS_EXTERN uint8_t *JS_WriteObject2(JSContext *ctx, size_t *psize, JSValue obj,
#define JS_READ_OBJ_SAB (1 << 2) /* allow SharedArrayBuffer */ #define JS_READ_OBJ_SAB (1 << 2) /* allow SharedArrayBuffer */
#define JS_READ_OBJ_REFERENCE (1 << 3) /* allow object references */ #define JS_READ_OBJ_REFERENCE (1 << 3) /* allow object references */
JS_EXTERN JSValue JS_ReadObject(JSContext *ctx, const uint8_t *buf, size_t buf_len, int flags); JS_EXTERN JSValue JS_ReadObject(JSContext *ctx, const uint8_t *buf, size_t buf_len, int flags);
JS_EXTERN JSValue JS_ReadObject2(JSContext *ctx, const uint8_t *buf, size_t buf_len,
int flags, uint8_t ***psab_tab, size_t *psab_tab_len);
/* instantiate and evaluate a bytecode function. Only used when /* instantiate and evaluate a bytecode function. Only used when
reading a script or module with JS_ReadObject() */ reading a script or module with JS_ReadObject() */
JS_EXTERN JSValue JS_EvalFunction(JSContext *ctx, JSValue fun_obj); JS_EXTERN JSValue JS_EvalFunction(JSContext *ctx, JSValue fun_obj);