Skip to content

Commit

Permalink
fix classes
Browse files Browse the repository at this point in the history
  • Loading branch information
xeioex committed Sep 10, 2024
1 parent 97279cc commit efbf18f
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 104 deletions.
73 changes: 29 additions & 44 deletions nginx/ngx_http_js_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -1029,13 +1029,6 @@ static ngx_http_js_entry_t ngx_http_methods[] = {

#if (NJS_HAVE_QUICKJS)

static JSClassID ngx_http_qjs_request_class_id;
static JSClassID ngx_http_qjs_periodic_class_id;
static JSClassID ngx_http_qjs_variables_class_id;
static JSClassID ngx_http_qjs_headers_in_class_id;
static JSClassID ngx_http_qjs_headers_out_class_id;


static const JSCFunctionListEntry ngx_http_qjs_ext_request[] = {
JS_CGETSET_DEF("args", ngx_http_qjs_ext_args, NULL),
JS_CFUNC_DEF("done", 0, ngx_http_qjs_ext_done),
Expand Down Expand Up @@ -4778,7 +4771,7 @@ ngx_http_qjs_ext_args(JSContext *cx, JSValueConst this_val)
ngx_http_request_t *r;
ngx_http_qjs_request_t *req;

req = JS_GetOpaque(this_val, ngx_http_qjs_request_class_id);
req = JS_GetOpaque(this_val, NGX_QJS_CLASS_ID_HTTP_REQUEST);
if (req == NULL) {
return JS_ThrowInternalError(cx, "\"this\" is not a request object");
}
Expand Down Expand Up @@ -4968,7 +4961,7 @@ ngx_http_qjs_ext_headers_in(JSContext *cx, JSValueConst this_val)
return JS_ThrowInternalError(cx, "\"this\" is not a request object");
}

obj = JS_NewObjectProtoClass(cx, JS_NULL, ngx_http_qjs_headers_in_class_id);
obj = JS_NewObjectProtoClass(cx, JS_NULL, NGX_QJS_CLASS_ID_HTTP_HEADERS_IN);

JS_SetOpaque(obj, r);

Expand All @@ -4988,7 +4981,7 @@ ngx_http_qjs_ext_headers_out(JSContext *cx, JSValueConst this_val)
}

obj = JS_NewObjectProtoClass(cx, JS_NULL,
ngx_http_qjs_headers_out_class_id);
NGX_QJS_CLASS_ID_HTTP_HEADERS_OUT);

JS_SetOpaque(obj, r);

Expand Down Expand Up @@ -5119,12 +5112,12 @@ ngx_http_qjs_ext_periodic_variables(JSContext *cx,
JSValue obj;
ngx_http_qjs_request_t *req;

req = JS_GetOpaque(this_val, ngx_http_qjs_periodic_class_id);
req = JS_GetOpaque(this_val, NGX_QJS_CLASS_ID_HTTP_PERIODIC);
if (req == NULL) {
return JS_ThrowInternalError(cx, "\"this\" is not a periodic object");
}

obj = JS_NewObjectProtoClass(cx, JS_NULL, ngx_http_qjs_variables_class_id);
obj = JS_NewObjectProtoClass(cx, JS_NULL, NGX_QJS_CLASS_ID_HTTP_VARS);

/*
* Using lowest bit of the pointer to store the buffer type.
Expand Down Expand Up @@ -5186,7 +5179,7 @@ ngx_http_qjs_ext_response_body(JSContext *cx, JSValueConst this_val, int type)
ngx_http_request_t *r;
ngx_http_qjs_request_t *req;

req = JS_GetOpaque(this_val, ngx_http_qjs_request_class_id);
req = JS_GetOpaque(this_val, NGX_QJS_CLASS_ID_HTTP_REQUEST);
if (req == NULL) {
return JS_ThrowInternalError(cx, "\"this\" is not a request object");
}
Expand Down Expand Up @@ -5241,7 +5234,7 @@ ngx_http_qjs_ext_request_body(JSContext *cx, JSValueConst this_val, int type)
ngx_http_request_t *r;
ngx_http_qjs_request_t *req;

req = JS_GetOpaque(this_val, ngx_http_qjs_request_class_id);
req = JS_GetOpaque(this_val, NGX_QJS_CLASS_ID_HTTP_REQUEST);
if (req == NULL) {
return JS_ThrowInternalError(cx, "\"this\" is not a request object");
}
Expand Down Expand Up @@ -5647,7 +5640,7 @@ ngx_http_qjs_subrequest_done(ngx_http_request_t *r, void *data, ngx_int_t rc)
cx = ctx->engine->u.qjs.ctx;

if (!JS_IsObject(ngx_qjs_arg(sctx->args[0]))) {
reply = ngx_http_qjs_request_make(cx, ngx_http_qjs_request_class_id, r);
reply = ngx_http_qjs_request_make(cx, NGX_QJS_CLASS_ID_HTTP_REQUEST, r);
if (JS_IsException(reply)) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"js subrequest reply creation failed");
Expand Down Expand Up @@ -6049,7 +6042,7 @@ ngx_http_qjs_ext_variables(JSContext *cx, JSValueConst this_val, int type)
return JS_ThrowInternalError(cx, "\"this\" is not a request object");
}

obj = JS_NewObjectProtoClass(cx, JS_NULL, ngx_http_qjs_variables_class_id);
obj = JS_NewObjectProtoClass(cx, JS_NULL, NGX_QJS_CLASS_ID_HTTP_VARS);

/*
* Using lowest bit of the pointer to store the buffer type.
Expand All @@ -6071,7 +6064,7 @@ ngx_http_qjs_variables_own_property(JSContext *cx, JSPropertyDescriptor *pdesc,
ngx_http_request_t *r;
ngx_http_variable_value_t *vv;

r = JS_GetOpaque(obj, ngx_http_qjs_variables_class_id);
r = JS_GetOpaque(obj, NGX_QJS_CLASS_ID_HTTP_VARS);

buffer_type = ((uintptr_t) r & 1) ? NGX_JS_BUFFER : NGX_JS_STRING;
r = (ngx_http_request_t *) ((uintptr_t) r & ~(uintptr_t) 1);
Expand Down Expand Up @@ -6151,7 +6144,7 @@ ngx_http_qjs_variables_set_property(JSContext *cx, JSValueConst obj,
ngx_http_variable_value_t *vv;
ngx_http_core_main_conf_t *cmcf;

r = JS_GetOpaque(obj, ngx_http_qjs_variables_class_id);
r = JS_GetOpaque(obj, NGX_QJS_CLASS_ID_HTTP_VARS);

r = (ngx_http_request_t *) ((uintptr_t) r & ~(uintptr_t) 1);

Expand Down Expand Up @@ -6279,7 +6272,7 @@ ngx_http_qjs_headers_in_own_property_names(JSContext *cx,
JSValue keys;
ngx_http_request_t *r;

r = JS_GetOpaque(obj, ngx_http_qjs_headers_in_class_id);
r = JS_GetOpaque(obj, NGX_QJS_CLASS_ID_HTTP_HEADERS_IN);
if (r == NULL) {
(void) JS_ThrowInternalError(cx, "\"this\" is not a headers_in object");
return -1;
Expand Down Expand Up @@ -6487,7 +6480,7 @@ ngx_http_qjs_headers_in_own_property(JSContext *cx, JSPropertyDescriptor *pdesc,
ngx_string(""),
};

r = JS_GetOpaque(obj, ngx_http_qjs_headers_in_class_id);
r = JS_GetOpaque(obj, NGX_QJS_CLASS_ID_HTTP_HEADERS_IN);
if (r == NULL) {
(void) JS_ThrowInternalError(cx, "\"this\" is not a headers_in object");
return -1;
Expand Down Expand Up @@ -6527,7 +6520,7 @@ ngx_http_qjs_headers_out_own_property_names(JSContext *cx,
JSValue keys;
ngx_http_request_t *r;

r = JS_GetOpaque(obj, ngx_http_qjs_headers_out_class_id);
r = JS_GetOpaque(obj, NGX_QJS_CLASS_ID_HTTP_HEADERS_OUT);
if (r == NULL) {
(void) JS_ThrowInternalError(cx, "\"this\" is not a headers_out"
" object");
Expand Down Expand Up @@ -7159,7 +7152,7 @@ ngx_http_qjs_headers_out_own_property(JSContext *cx,
ngx_str_t name;
ngx_http_request_t *r;

r = JS_GetOpaque(obj, ngx_http_qjs_headers_out_class_id);
r = JS_GetOpaque(obj, NGX_QJS_CLASS_ID_HTTP_HEADERS_OUT);
if (r == NULL) {
(void) JS_ThrowInternalError(cx, "\"this\" is not a headers_out"
" object");
Expand Down Expand Up @@ -7199,7 +7192,7 @@ ngx_http_qjs_headers_out_define_own_property(JSContext *cx,
ngx_str_t name;
ngx_http_request_t *r;

r = JS_GetOpaque(obj, ngx_http_qjs_headers_out_class_id);
r = JS_GetOpaque(obj, NGX_QJS_CLASS_ID_HTTP_HEADERS_OUT);
if (r == NULL) {
(void) JS_ThrowInternalError(cx, "\"this\" is not a headers_out"
" object");
Expand Down Expand Up @@ -7239,7 +7232,7 @@ ngx_http_qjs_headers_out_delete_property(JSContext *cx,
ngx_str_t name;
ngx_http_request_t *r;

r = JS_GetOpaque(obj, ngx_http_qjs_headers_out_class_id);
r = JS_GetOpaque(obj, NGX_QJS_CLASS_ID_HTTP_HEADERS_OUT);
if (r == NULL) {
(void) JS_ThrowInternalError(cx, "\"this\" is not a headers_out"
" object");
Expand Down Expand Up @@ -7372,7 +7365,7 @@ ngx_http_qjs_request(JSValueConst val)
{
ngx_http_qjs_request_t *req;

req = JS_GetOpaque(val, ngx_http_qjs_request_class_id);
req = JS_GetOpaque(val, NGX_QJS_CLASS_ID_HTTP_REQUEST);
if (req == NULL) {
return NULL;
}
Expand Down Expand Up @@ -7421,7 +7414,7 @@ ngx_http_qjs_request_finalizer(JSRuntime *rt, JSValue val)
{
ngx_http_qjs_request_t *req;

req = JS_GetOpaque(val, ngx_http_qjs_request_class_id);
req = JS_GetOpaque(val, NGX_QJS_CLASS_ID_HTTP_REQUEST);
if (req == NULL) {
return;
}
Expand Down Expand Up @@ -7451,9 +7444,9 @@ ngx_engine_qjs_clone(ngx_js_ctx_t *ctx, ngx_js_loc_conf_t *cf,
cx = engine->u.qjs.ctx;

if (!JS_IsRegisteredClass(JS_GetRuntime(cx),
ngx_http_qjs_request_class_id))
NGX_QJS_CLASS_ID_HTTP_REQUEST))
{
if (JS_NewClass(JS_GetRuntime(cx), ngx_http_qjs_request_class_id,
if (JS_NewClass(JS_GetRuntime(cx), NGX_QJS_CLASS_ID_HTTP_REQUEST,
&ngx_http_qjs_request_class) < 0)
{
return NULL;
Expand All @@ -7463,9 +7456,9 @@ ngx_engine_qjs_clone(ngx_js_ctx_t *ctx, ngx_js_loc_conf_t *cf,
JS_SetPropertyFunctionList(cx, proto, ngx_http_qjs_ext_request,
njs_nitems(ngx_http_qjs_ext_request));

JS_SetClassProto(cx, ngx_http_qjs_request_class_id, proto);
JS_SetClassProto(cx, NGX_QJS_CLASS_ID_HTTP_REQUEST, proto);

if (JS_NewClass(JS_GetRuntime(cx), ngx_http_qjs_periodic_class_id,
if (JS_NewClass(JS_GetRuntime(cx), NGX_QJS_CLASS_ID_HTTP_PERIODIC,
&ngx_http_qjs_periodic_class) < 0)
{
return NULL;
Expand All @@ -7475,21 +7468,21 @@ ngx_engine_qjs_clone(ngx_js_ctx_t *ctx, ngx_js_loc_conf_t *cf,
JS_SetPropertyFunctionList(cx, proto, ngx_http_qjs_ext_periodic,
njs_nitems(ngx_http_qjs_ext_periodic));

JS_SetClassProto(cx, ngx_http_qjs_periodic_class_id, proto);
JS_SetClassProto(cx, NGX_QJS_CLASS_ID_HTTP_PERIODIC, proto);

if (JS_NewClass(JS_GetRuntime(cx), ngx_http_qjs_variables_class_id,
if (JS_NewClass(JS_GetRuntime(cx), NGX_QJS_CLASS_ID_HTTP_VARS,
&ngx_http_qjs_variables_class) < 0)
{
return NULL;
}

if (JS_NewClass(JS_GetRuntime(cx), ngx_http_qjs_headers_in_class_id,
if (JS_NewClass(JS_GetRuntime(cx), NGX_QJS_CLASS_ID_HTTP_HEADERS_IN,
&ngx_http_qjs_headers_in_class) < 0)
{
return NULL;
}

if (JS_NewClass(JS_GetRuntime(cx), ngx_http_qjs_headers_out_class_id,
if (JS_NewClass(JS_GetRuntime(cx), NGX_QJS_CLASS_ID_HTTP_HEADERS_OUT,
&ngx_http_qjs_headers_out_class) < 0)
{
return NULL;
Expand All @@ -7500,10 +7493,10 @@ ngx_engine_qjs_clone(ngx_js_ctx_t *ctx, ngx_js_loc_conf_t *cf,
hctx->body_filter = ngx_http_qjs_body_filter;

if (proto_id == ngx_http_js_request_proto_id) {
proto_id = ngx_http_qjs_request_class_id;
proto_id = NGX_QJS_CLASS_ID_HTTP_REQUEST;

} else if (proto_id == ngx_http_js_periodic_session_proto_id) {
proto_id = ngx_http_qjs_periodic_class_id;
proto_id = NGX_QJS_CLASS_ID_HTTP_PERIODIC;
}

ngx_qjs_arg(hctx->args[0]) = ngx_http_qjs_request_make(cx, proto_id,
Expand Down Expand Up @@ -7558,14 +7551,6 @@ ngx_http_js_init(ngx_conf_t *cf)
ngx_http_next_body_filter = ngx_http_top_body_filter;
ngx_http_top_body_filter = ngx_http_js_body_filter;

#if (NJS_HAVE_QUICKJS)
JS_NewClassID(&ngx_http_qjs_request_class_id);
JS_NewClassID(&ngx_http_qjs_periodic_class_id);
JS_NewClassID(&ngx_http_qjs_variables_class_id);
JS_NewClassID(&ngx_http_qjs_headers_in_class_id);
JS_NewClassID(&ngx_http_qjs_headers_out_class_id);
#endif

return NGX_OK;
}

Expand Down
18 changes: 7 additions & 11 deletions nginx/ngx_js.c
Original file line number Diff line number Diff line change
Expand Up @@ -427,8 +427,6 @@ static njs_int_t ngx_js_console_proto_id;

#if (NJS_HAVE_QUICKJS)

static JSClassID ngx_qjs_console_class_id;

static const JSCFunctionListEntry ngx_qjs_ext_ngx[] = {
JS_CGETSET_DEF("build", ngx_qjs_ext_build, NULL),
JS_CGETSET_DEF("conf_prefix", ngx_qjs_ext_conf_prefix, NULL),
Expand Down Expand Up @@ -1713,7 +1711,7 @@ ngx_qjs_console_finalizer(JSRuntime *rt, JSValue val)
{
ngx_js_console_t *console;

console = JS_GetOpaque(val, ngx_qjs_console_class_id);
console = JS_GetOpaque(val, NGX_QJS_CLASS_ID_CONSOLE);
if (console == (void *) 1) {
return;
}
Expand Down Expand Up @@ -1776,7 +1774,7 @@ ngx_qjs_ext_console_time(JSContext *cx, JSValueConst this_val, int argc,

static const ngx_str_t default_label = ngx_string("default");

console = JS_GetOpaque(this_val, ngx_qjs_console_class_id);
console = JS_GetOpaque(this_val, NGX_QJS_CLASS_ID_CONSOLE);
if (console == NULL) {
return JS_ThrowInternalError(cx, "this is not a console object");
}
Expand Down Expand Up @@ -1865,7 +1863,7 @@ ngx_qjs_ext_console_time_end(JSContext *cx, JSValueConst this_val, int argc,

ns = ngx_js_monotonic_time();

console = JS_GetOpaque(this_val, ngx_qjs_console_class_id);
console = JS_GetOpaque(this_val, NGX_QJS_CLASS_ID_CONSOLE);
if (console == NULL) {
return JS_ThrowInternalError(cx, "this is not a console object");
}
Expand Down Expand Up @@ -2102,12 +2100,10 @@ ngx_qjs_core_init(JSContext *cx, const char *name)
JSValue global_obj, proto, obj;
JSModuleDef *m;

JS_NewClassID(&ngx_qjs_console_class_id);

if (!JS_IsRegisteredClass(JS_GetRuntime(cx),
ngx_qjs_console_class_id))
NGX_QJS_CLASS_ID_CONSOLE))
{
if (JS_NewClass(JS_GetRuntime(cx), ngx_qjs_console_class_id,
if (JS_NewClass(JS_GetRuntime(cx), NGX_QJS_CLASS_ID_CONSOLE,
&ngx_qjs_console_class) < 0)
{
return NULL;
Expand All @@ -2121,7 +2117,7 @@ ngx_qjs_core_init(JSContext *cx, const char *name)
JS_SetPropertyFunctionList(cx, proto, ngx_qjs_ext_console,
njs_nitems(ngx_qjs_ext_console));

JS_SetClassProto(cx, ngx_qjs_console_class_id, proto);
JS_SetClassProto(cx, NGX_QJS_CLASS_ID_CONSOLE, proto);
}

obj = JS_NewObject(cx);
Expand All @@ -2143,7 +2139,7 @@ ngx_qjs_core_init(JSContext *cx, const char *name)
return NULL;
}

obj = JS_NewObjectClass(cx, ngx_qjs_console_class_id);
obj = JS_NewObjectClass(cx, NGX_QJS_CLASS_ID_CONSOLE);
if (JS_IsException(obj)) {
JS_FreeValue(cx, global_obj);
return NULL;
Expand Down
20 changes: 20 additions & 0 deletions nginx/ngx_js.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,26 @@

#define ngx_js_buffer_type(btype) ((btype) & ~NGX_JS_DEPRECATED)

/*
* This static table solves the problem of a native QuickJS apporach
* which uses a static variables of type JSClassID and JS_NewClassID() to
* allocate class ids for custom classes. The static variables apporach
* causes a problem when two modules linked with -Wl,-Bsymbolic-functions flag
* are loaded dynamically.
*/

#define NGX_QJS_CLASS_ID_OFFSET (QJS_CORE_CLASS_ID_LAST)
#define NGX_QJS_CLASS_ID_CONSOLE (NGX_QJS_CLASS_ID_OFFSET + 1)
#define NGX_QJS_CLASS_ID_HTTP_REQUEST (NGX_QJS_CLASS_ID_OFFSET + 2)
#define NGX_QJS_CLASS_ID_HTTP_PERIODIC (NGX_QJS_CLASS_ID_OFFSET + 3)
#define NGX_QJS_CLASS_ID_HTTP_VARS (NGX_QJS_CLASS_ID_OFFSET + 4)
#define NGX_QJS_CLASS_ID_HTTP_HEADERS_IN (NGX_QJS_CLASS_ID_OFFSET + 5)
#define NGX_QJS_CLASS_ID_HTTP_HEADERS_OUT (NGX_QJS_CLASS_ID_OFFSET + 6)
#define NGX_QJS_CLASS_ID_STREAM_SESSION (NGX_QJS_CLASS_ID_OFFSET + 7)
#define NGX_QJS_CLASS_ID_STREAM_PERIODIC (NGX_QJS_CLASS_ID_OFFSET + 8)
#define NGX_QJS_CLASS_ID_STREAM_FLAGS (NGX_QJS_CLASS_ID_OFFSET + 9)
#define NGX_QJS_CLASS_ID_STREAM_VARS (NGX_QJS_CLASS_ID_OFFSET + 10)


typedef struct ngx_js_loc_conf_s ngx_js_loc_conf_t;
typedef struct ngx_js_event_s ngx_js_event_t;
Expand Down
Loading

0 comments on commit efbf18f

Please sign in to comment.