From 4735931ace321752c387dae04c8b217ef22897ee Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Sun, 20 Nov 2022 23:15:01 +0800 Subject: Var: separating nxt_tstr_t from nxt_var_t. It's for the introduction of njs support. For each option that supports native variable and JS template literals introduced next, it's unified as template string. No functional changes. --- src/nxt_tstr.c | 223 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 src/nxt_tstr.c (limited to 'src/nxt_tstr.c') diff --git a/src/nxt_tstr.c b/src/nxt_tstr.c new file mode 100644 index 00000000..dff61952 --- /dev/null +++ b/src/nxt_tstr.c @@ -0,0 +1,223 @@ + +/* + * Copyright (C) NGINX, Inc. + */ + +#include + + +typedef enum { + NXT_TSTR_CONST = 0, + NXT_TSTR_VAR, +} nxt_tstr_type_t; + + +struct nxt_tstr_s { + nxt_str_t str; + nxt_var_t *var; + nxt_tstr_flags_t flags; + nxt_tstr_type_t type; +}; + + +struct nxt_tstr_query_s { + nxt_mp_t *pool; + + nxt_tstr_state_t *state; + nxt_var_cache_t *cache; + + nxt_uint_t waiting; + nxt_uint_t failed; /* 1 bit */ + + void *ctx; + void *data; + + nxt_work_handler_t ready; + nxt_work_handler_t error; +}; + + +nxt_tstr_state_t * +nxt_tstr_state_new(nxt_mp_t *mp) +{ + nxt_tstr_state_t *state; + + state = nxt_mp_get(mp, sizeof(nxt_tstr_state_t)); + if (nxt_slow_path(state == NULL)) { + return NULL; + } + + state->pool = mp; + + state->var_fields = nxt_array_create(mp, 4, sizeof(nxt_var_field_t)); + if (nxt_slow_path(state->var_fields == NULL)) { + return NULL; + } + + return state; +} + + +nxt_tstr_t * +nxt_tstr_compile(nxt_tstr_state_t *state, nxt_str_t *str, + nxt_tstr_flags_t flags) +{ + u_char *p; + nxt_tstr_t *tstr; + nxt_bool_t strz; + + strz = (flags & NXT_TSTR_STRZ) != 0; + + tstr = nxt_mp_get(state->pool, sizeof(nxt_tstr_t)); + if (nxt_slow_path(tstr == NULL)) { + return NULL; + } + + tstr->str.length = str->length + strz; + + tstr->str.start = nxt_mp_nget(state->pool, tstr->str.length); + if (nxt_slow_path(tstr->str.start == NULL)) { + return NULL; + } + + p = nxt_cpymem(tstr->str.start, str->start, str->length); + + if (strz) { + *p = '\0'; + } + + tstr->flags = flags; + + p = nxt_memchr(str->start, '$', str->length); + + if (p != NULL) { + tstr->type = NXT_TSTR_VAR; + + tstr->var = nxt_var_compile(&tstr->str, state->pool, state->var_fields); + if (nxt_slow_path(tstr->var == NULL)) { + return NULL; + } + + } else { + tstr->type = NXT_TSTR_CONST; + } + + return tstr; +} + + +nxt_int_t +nxt_tstr_test(nxt_tstr_state_t *state, nxt_str_t *str, u_char *error) +{ + return nxt_var_test(str, state->var_fields, error); +} + + +nxt_bool_t +nxt_tstr_is_const(nxt_tstr_t *tstr) +{ + return (tstr->type == NXT_TSTR_CONST); +} + + +void +nxt_tstr_str(nxt_tstr_t *tstr, nxt_str_t *str) +{ + *str = tstr->str; + + if (tstr->flags & NXT_TSTR_STRZ) { + str->length--; + } +} + + +nxt_int_t +nxt_tstr_query_init(nxt_tstr_query_t **query_p, nxt_tstr_state_t *state, + nxt_var_cache_t *cache, void *ctx, nxt_mp_t *mp) +{ + nxt_tstr_query_t *query; + + query = *query_p; + + if (*query_p == NULL) { + query = nxt_mp_zget(mp, sizeof(nxt_tstr_query_t)); + if (nxt_slow_path(query == NULL)) { + return NXT_ERROR; + } + } + + query->pool = mp; + query->state = state; + query->cache = cache; + query->ctx = ctx; + + *query_p = query; + + return NXT_OK; +} + + +void +nxt_tstr_query(nxt_task_t *task, nxt_tstr_query_t *query, nxt_tstr_t *tstr, + nxt_str_t *val) +{ + nxt_int_t ret; + + if (nxt_tstr_is_const(tstr)) { + nxt_tstr_str(tstr, val); + return; + } + + if (nxt_slow_path(query->failed)) { + return; + } + + ret = nxt_var_interpreter(task, query->cache, tstr->var, val, query->ctx, + tstr->flags & NXT_TSTR_LOGGING); + if (nxt_slow_path(ret != NXT_OK)) { + query->failed = 1; + return; + } + + if (tstr->flags & NXT_TSTR_STRZ) { + val->length--; + } + +#if (NXT_DEBUG) + nxt_str_t str; + + nxt_tstr_str(tstr, &str); + + nxt_debug(task, "tstr: \"%V\" -> \"%V\"", &str, val); +#endif +} + + +void +nxt_tstr_query_resolve(nxt_task_t *task, nxt_tstr_query_t *query, void *data, + nxt_work_handler_t ready, nxt_work_handler_t error) +{ + query->data = data; + query->ready = ready; + query->error = error; + + if (query->waiting == 0) { + nxt_work_queue_add(&task->thread->engine->fast_work_queue, + query->failed ? query->error : query->ready, + task, query->ctx, query->data); + } +} + + +void +nxt_tstr_query_handle(nxt_task_t *task, nxt_tstr_query_t *query, + nxt_bool_t failed) +{ + query->failed |= failed; + + if (--query->waiting == 0) { + nxt_work_queue_add(&task->thread->engine->fast_work_queue, + query->failed ? query->error : query->ready, + task, query->ctx, query->data); + } +} -- cgit From 4d6d146e920667a8afeacd355e4fb6a94387066e Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Sun, 20 Nov 2022 23:16:51 +0800 Subject: Basic njs support. --- src/nxt_tstr.c | 128 +++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 111 insertions(+), 17 deletions(-) (limited to 'src/nxt_tstr.c') diff --git a/src/nxt_tstr.c b/src/nxt_tstr.c index dff61952..fd01797c 100644 --- a/src/nxt_tstr.c +++ b/src/nxt_tstr.c @@ -9,12 +9,22 @@ typedef enum { NXT_TSTR_CONST = 0, NXT_TSTR_VAR, +#if (NXT_HAVE_NJS) + NXT_TSTR_JS, +#endif } nxt_tstr_type_t; struct nxt_tstr_s { nxt_str_t str; - nxt_var_t *var; + + union { + nxt_var_t *var; +#if (NXT_HAVE_NJS) + nxt_js_t *js; +#endif + } u; + nxt_tstr_flags_t flags; nxt_tstr_type_t type; }; @@ -24,7 +34,7 @@ struct nxt_tstr_query_s { nxt_mp_t *pool; nxt_tstr_state_t *state; - nxt_var_cache_t *cache; + nxt_tstr_cache_t *cache; nxt_uint_t waiting; nxt_uint_t failed; /* 1 bit */ @@ -37,8 +47,12 @@ struct nxt_tstr_query_s { }; +#define nxt_tstr_is_js(str) \ + nxt_strchr_start(str, '`') + + nxt_tstr_state_t * -nxt_tstr_state_new(nxt_mp_t *mp) +nxt_tstr_state_new(nxt_mp_t *mp, nxt_bool_t test) { nxt_tstr_state_t *state; @@ -48,12 +62,20 @@ nxt_tstr_state_new(nxt_mp_t *mp) } state->pool = mp; + state->test = test; state->var_fields = nxt_array_create(mp, 4, sizeof(nxt_var_field_t)); if (nxt_slow_path(state->var_fields == NULL)) { return NULL; } +#if (NXT_HAVE_NJS) + state->jcf = nxt_js_conf_new(mp); + if (nxt_slow_path(state->jcf == NULL)) { + return NULL; + } +#endif + return state; } @@ -88,18 +110,38 @@ nxt_tstr_compile(nxt_tstr_state_t *state, nxt_str_t *str, tstr->flags = flags; - p = nxt_memchr(str->start, '$', str->length); + if (nxt_tstr_is_js(str)) { + +#if (NXT_HAVE_NJS) + + nxt_str_t tpl; - if (p != NULL) { - tstr->type = NXT_TSTR_VAR; + tstr->type = NXT_TSTR_JS; - tstr->var = nxt_var_compile(&tstr->str, state->pool, state->var_fields); - if (nxt_slow_path(tstr->var == NULL)) { + nxt_tstr_str(tstr, &tpl); + + tstr->u.js = nxt_js_add_tpl(state->jcf, &tpl, strz); + if (nxt_slow_path(tstr->u.js == NULL)) { return NULL; } +#endif + } else { - tstr->type = NXT_TSTR_CONST; + p = memchr(str->start, '$', str->length); + + if (p != NULL) { + tstr->type = NXT_TSTR_VAR; + + tstr->u.var = nxt_var_compile(&tstr->str, state->pool, + state->var_fields); + if (nxt_slow_path(tstr->u.var == NULL)) { + return NULL; + } + + } else { + tstr->type = NXT_TSTR_CONST; + } } return tstr; @@ -109,7 +151,46 @@ nxt_tstr_compile(nxt_tstr_state_t *state, nxt_str_t *str, nxt_int_t nxt_tstr_test(nxt_tstr_state_t *state, nxt_str_t *str, u_char *error) { - return nxt_var_test(str, state->var_fields, error); + u_char *p; + + if (nxt_tstr_is_js(str)) { +#if (NXT_HAVE_NJS) + return nxt_js_test(state->jcf, str, error); + +#else + nxt_sprintf(error, error + NXT_MAX_ERROR_STR, + "Unit is built without support of njs: " + "\"--njs\" ./configure option is missing."); + return NXT_ERROR; +#endif + + } else { + p = memchr(str->start, '$', str->length); + + if (p != NULL) { + return nxt_var_test(str, state->var_fields, error); + } + } + + return NXT_OK; +} + + +nxt_int_t +nxt_tstr_state_done(nxt_tstr_state_t *state, u_char *error) +{ +#if (NXT_HAVE_NJS) + if (!state->test) { + nxt_int_t ret; + + ret = nxt_js_compile(state->jcf); + if (nxt_slow_path(ret != NXT_OK)) { + return NXT_ERROR; + } + } +#endif + + return NXT_OK; } @@ -133,7 +214,7 @@ nxt_tstr_str(nxt_tstr_t *tstr, nxt_str_t *str) nxt_int_t nxt_tstr_query_init(nxt_tstr_query_t **query_p, nxt_tstr_state_t *state, - nxt_var_cache_t *cache, void *ctx, nxt_mp_t *mp) + nxt_tstr_cache_t *cache, void *ctx, nxt_mp_t *mp) { nxt_tstr_query_t *query; @@ -172,11 +253,24 @@ nxt_tstr_query(nxt_task_t *task, nxt_tstr_query_t *query, nxt_tstr_t *tstr, return; } - ret = nxt_var_interpreter(task, query->cache, tstr->var, val, query->ctx, - tstr->flags & NXT_TSTR_LOGGING); - if (nxt_slow_path(ret != NXT_OK)) { - query->failed = 1; - return; + if (tstr->type == NXT_TSTR_VAR) { + ret = nxt_var_interpreter(task, &query->cache->var, tstr->u.var, val, + query->ctx, tstr->flags & NXT_TSTR_LOGGING); + + if (nxt_slow_path(ret != NXT_OK)) { + query->failed = 1; + return; + } + + } else { +#if (NXT_HAVE_NJS) + ret = nxt_js_call(task, &query->cache->js, tstr->u.js, val, query->ctx); + + if (nxt_slow_path(ret != NXT_OK)) { + query->failed = 1; + return; + } +#endif } if (tstr->flags & NXT_TSTR_STRZ) { @@ -188,7 +282,7 @@ nxt_tstr_query(nxt_task_t *task, nxt_tstr_query_t *query, nxt_tstr_t *tstr, nxt_tstr_str(tstr, &str); - nxt_debug(task, "tstr: \"%V\" -> \"%V\"", &str, val); + nxt_debug(task, "tstr query: \"%V\", result: \"%V\"", &str, val); #endif } -- cgit