Make JS_NewClassID thread aware

It's as thread-safe as JSRuntime, which isn't thread-safe, but multiple
threads can now allocate them on different runtimes without a problem.
This commit is contained in:
Saúl Ibarra Corretgé 2023-11-20 12:16:46 +01:00
parent b56a82d19f
commit 5ce2957e23
4 changed files with 18 additions and 16 deletions

View file

@ -123,10 +123,11 @@ static const JSCFunctionListEntry js_point_proto_funcs[] = {
static int js_point_init(JSContext *ctx, JSModuleDef *m) static int js_point_init(JSContext *ctx, JSModuleDef *m)
{ {
JSValue point_proto, point_class; JSValue point_proto, point_class;
JSRuntime *rt = JS_GetRuntime(ctx);
/* create the Point class */ /* create the Point class */
JS_NewClassID(&js_point_class_id); JS_NewClassID(rt, &js_point_class_id);
JS_NewClass(JS_GetRuntime(ctx), js_point_class_id, &js_point_class); JS_NewClass(rt, js_point_class_id, &js_point_class);
point_proto = JS_NewObject(ctx); point_proto = JS_NewObject(ctx);
JS_SetPropertyFunctionList(ctx, point_proto, js_point_proto_funcs, countof(js_point_proto_funcs)); JS_SetPropertyFunctionList(ctx, point_proto, js_point_proto_funcs, countof(js_point_proto_funcs));

View file

@ -1516,12 +1516,13 @@ static const JSCFunctionListEntry js_std_file_proto_funcs[] = {
static int js_std_init(JSContext *ctx, JSModuleDef *m) static int js_std_init(JSContext *ctx, JSModuleDef *m)
{ {
JSValue proto; JSValue proto;
JSRuntime *rt = JS_GetRuntime(ctx);
/* FILE class */ /* FILE class */
/* the class ID is created once */ /* the class ID is created once */
JS_NewClassID(&js_std_file_class_id); JS_NewClassID(rt, &js_std_file_class_id);
/* the class is created once per runtime */ /* the class is created once per runtime */
JS_NewClass(JS_GetRuntime(ctx), js_std_file_class_id, &js_std_file_class); JS_NewClass(rt, js_std_file_class_id, &js_std_file_class);
proto = JS_NewObject(ctx); proto = JS_NewObject(ctx);
JS_SetPropertyFunctionList(ctx, proto, js_std_file_proto_funcs, JS_SetPropertyFunctionList(ctx, proto, js_std_file_proto_funcs,
countof(js_std_file_proto_funcs)); countof(js_std_file_proto_funcs));
@ -3658,20 +3659,20 @@ static const JSCFunctionListEntry js_os_funcs[] = {
static int js_os_init(JSContext *ctx, JSModuleDef *m) static int js_os_init(JSContext *ctx, JSModuleDef *m)
{ {
JSRuntime *rt = JS_GetRuntime(ctx);
os_poll_func = js_os_poll; os_poll_func = js_os_poll;
/* OSTimer class */ /* OSTimer class */
JS_NewClassID(&js_os_timer_class_id); JS_NewClassID(rt, &js_os_timer_class_id);
JS_NewClass(JS_GetRuntime(ctx), js_os_timer_class_id, &js_os_timer_class); JS_NewClass(rt, js_os_timer_class_id, &js_os_timer_class);
#ifdef USE_WORKER #ifdef USE_WORKER
{ {
JSRuntime *rt = JS_GetRuntime(ctx);
JSThreadState *ts = JS_GetRuntimeOpaque(rt); JSThreadState *ts = JS_GetRuntimeOpaque(rt);
JSValue proto, obj; JSValue proto, obj;
/* Worker class */ /* Worker class */
JS_NewClassID(&js_worker_class_id); JS_NewClassID(rt, &js_worker_class_id);
JS_NewClass(JS_GetRuntime(ctx), js_worker_class_id, &js_worker_class); JS_NewClass(rt, js_worker_class_id, &js_worker_class);
proto = JS_NewObject(ctx); proto = JS_NewObject(ctx);
JS_SetPropertyFunctionList(ctx, proto, js_worker_proto_funcs, countof(js_worker_proto_funcs)); JS_SetPropertyFunctionList(ctx, proto, js_worker_proto_funcs, countof(js_worker_proto_funcs));

View file

@ -228,6 +228,7 @@ struct JSRuntime {
JSAtomStruct **atom_array; JSAtomStruct **atom_array;
int atom_free_index; /* 0 = none */ int atom_free_index; /* 0 = none */
JSClassID js_class_id_alloc; /* counter for user defined classes */
int class_count; /* size of class_array */ int class_count; /* size of class_array */
JSClass *class_array; JSClass *class_array;
@ -1149,7 +1150,6 @@ static const JSClassExoticMethods js_arguments_exotic_methods;
static const JSClassExoticMethods js_string_exotic_methods; static const JSClassExoticMethods js_string_exotic_methods;
static const JSClassExoticMethods js_proxy_exotic_methods; static const JSClassExoticMethods js_proxy_exotic_methods;
static const JSClassExoticMethods js_module_ns_exotic_methods; static const JSClassExoticMethods js_module_ns_exotic_methods;
static JSClassID js_class_id_alloc = JS_CLASS_INIT_COUNT;
static int compare_u32(uint32_t a, uint32_t b) static int compare_u32(uint32_t a, uint32_t b)
{ {
@ -1483,6 +1483,8 @@ JSRuntime *JS_NewRuntime2(const JSMallocFunctions *mf, void *opaque)
if (init_shape_hash(rt)) if (init_shape_hash(rt))
goto fail; goto fail;
rt->js_class_id_alloc = JS_CLASS_INIT_COUNT;
rt->stack_size = JS_DEFAULT_STACK_SIZE; rt->stack_size = JS_DEFAULT_STACK_SIZE;
JS_UpdateStackTop(rt); JS_UpdateStackTop(rt);
@ -3181,13 +3183,11 @@ static inline BOOL JS_IsEmptyString(JSValueConst v)
/* JSClass support */ /* JSClass support */
/* a new class ID is allocated if *pclass_id != 0 */ /* a new class ID is allocated if *pclass_id != 0 */
JSClassID JS_NewClassID(JSClassID *pclass_id) JSClassID JS_NewClassID(JSRuntime *rt, JSClassID *pclass_id)
{ {
JSClassID class_id; JSClassID class_id = *pclass_id;
/* XXX: make it thread safe */
class_id = *pclass_id;
if (class_id == 0) { if (class_id == 0) {
class_id = js_class_id_alloc++; class_id = rt->js_class_id_alloc++;
*pclass_id = class_id; *pclass_id = class_id;
} }
return class_id; return class_id;

View file

@ -484,7 +484,7 @@ typedef struct JSClassDef {
JSClassExoticMethods *exotic; JSClassExoticMethods *exotic;
} JSClassDef; } JSClassDef;
JSClassID JS_NewClassID(JSClassID *pclass_id); JSClassID JS_NewClassID(JSRuntime *rt, JSClassID *pclass_id);
int JS_NewClass(JSRuntime *rt, JSClassID class_id, const JSClassDef *class_def); int JS_NewClass(JSRuntime *rt, JSClassID class_id, const JSClassDef *class_def);
int JS_IsRegisteredClass(JSRuntime *rt, JSClassID class_id); int JS_IsRegisteredClass(JSRuntime *rt, JSClassID class_id);