[njs] QueryString: module is rewritten using public API.
Dmitry Volyntsev
xeioex at nginx.com
Wed May 3 04:13:31 UTC 2023
details: https://hg.nginx.org/njs/rev/fd956d2a25a3
branches:
changeset: 2101:fd956d2a25a3
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Tue May 02 20:50:55 2023 -0700
description:
QueryString: module is rewritten using public API.
diffstat:
external/njs_query_string_module.c | 561 +++++++++++++++---------------------
src/njs.h | 8 +
src/njs_value.c | 17 +
src/njs_value_conversion.h | 25 -
src/njs_vm.c | 25 +
src/test/njs_unit_test.c | 10 +-
6 files changed, 289 insertions(+), 357 deletions(-)
diffs (truncated from 1114 to 1000 lines):
diff -r b2cbf06ba017 -r fd956d2a25a3 external/njs_query_string_module.c
--- a/external/njs_query_string_module.c Tue May 02 20:50:52 2023 -0700
+++ b/external/njs_query_string_module.c Tue May 02 20:50:55 2023 -0700
@@ -6,7 +6,8 @@
*/
-#include <njs_main.h>
+#include <njs.h>
+#include <njs_string.h>
static njs_int_t njs_query_string_parser(njs_vm_t *vm, u_char *query,
@@ -108,48 +109,15 @@ njs_module_t njs_query_string_module =
};
-static const njs_value_t njs_escape_str = njs_string("escape");
-static const njs_value_t njs_unescape_str = njs_string("unescape");
-static const njs_value_t njs_encode_uri_str =
- njs_long_string("encodeURIComponent");
-static const njs_value_t njs_decode_uri_str =
- njs_long_string("decodeURIComponent");
-static const njs_value_t njs_max_keys_str = njs_string("maxKeys");
+static const njs_str_t njs_escape_str = njs_str("escape");
+static const njs_str_t njs_unescape_str = njs_str("unescape");
+static const njs_str_t njs_encode_uri_str = njs_str("encodeURIComponent");
+static const njs_str_t njs_decode_uri_str = njs_str("decodeURIComponent");
+static const njs_str_t njs_max_keys_str = njs_str("maxKeys");
static const njs_str_t njs_sep_default = njs_str("&");
static const njs_str_t njs_eq_default = njs_str("=");
-static const njs_value_t njs_unescape_default =
- njs_native_function(njs_query_string_unescape, 1);
-
-
-static njs_object_t *
-njs_query_string_object_alloc(njs_vm_t *vm)
-{
- njs_object_t *obj;
-
- obj = njs_mp_alloc(vm->mem_pool, sizeof(njs_object_t));
-
- if (njs_fast_path(obj != NULL)) {
- njs_lvlhsh_init(&obj->hash);
- njs_lvlhsh_init(&obj->shared_hash);
- obj->type = NJS_OBJECT;
- obj->shared = 0;
- obj->extensible = 1;
- obj->error_data = 0;
- obj->fast_array = 0;
-
- obj->__proto__ = NULL;
- obj->slots = NULL;
-
- return obj;
- }
-
- njs_memory_error(vm);
-
- return NULL;
-}
-
static njs_int_t
njs_query_string_decode(njs_vm_t *vm, njs_value_t *value, const u_char *start,
@@ -157,7 +125,6 @@ njs_query_string_decode(njs_vm_t *vm, nj
{
u_char *dst;
size_t length;
- ssize_t str_size;
uint32_t cp;
njs_int_t ret;
njs_chb_t chain;
@@ -185,7 +152,7 @@ njs_query_string_decode(njs_vm_t *vm, nj
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
};
- njs_chb_init(&chain, vm->mem_pool);
+ njs_chb_init(&chain, njs_vm_memory_pool(vm));
njs_utf8_decode_init(&ctx);
cp = 0;
@@ -240,21 +207,7 @@ njs_query_string_decode(njs_vm_t *vm, nj
length++;
}
- str_size = njs_chb_size(&chain);
- if (njs_slow_path(str_size < 0)) {
- goto failed;
- }
-
- dst = njs_string_alloc(vm, value, str_size, length);
- if (njs_slow_path(dst == NULL)) {
- goto failed;
- }
-
- njs_chb_join_to(&chain, dst);
-
- ret = NJS_OK;
-
-failed:
+ ret = njs_vm_value_string_create_chb(vm, value, &chain);
njs_chb_destroy(&chain);
@@ -265,7 +218,18 @@ failed:
njs_inline njs_bool_t
njs_query_string_is_native_decoder(njs_function_t *decoder)
{
- return decoder->native && decoder->u.native == njs_query_string_unescape;
+ njs_opaque_value_t function;
+ njs_function_native_t native;
+
+ if (decoder == NULL) {
+ return 1;
+ }
+
+ njs_value_function_set(njs_value_arg(&function), decoder);
+
+ native = njs_value_native_function(njs_value_arg(&function));
+
+ return native == njs_query_string_unescape;
}
@@ -274,80 +238,107 @@ njs_query_string_append(njs_vm_t *vm, nj
size_t key_size, const u_char *val, size_t val_size,
njs_function_t *decoder)
{
- uint32_t key_length, val_length;
- njs_int_t ret;
- njs_array_t *array;
- njs_value_t name, value, retval;
+ njs_int_t ret;
+ njs_value_t *push;
+ njs_opaque_value_t array, name, value, retval;
if (njs_query_string_is_native_decoder(decoder)) {
- ret = njs_query_string_decode(vm, &name, key, key_size);
+ ret = njs_query_string_decode(vm, njs_value_arg(&name), key, key_size);
if (njs_slow_path(ret != NJS_OK)) {
return ret;
}
- ret = njs_query_string_decode(vm, &value, val, val_size);
+ ret = njs_query_string_decode(vm, njs_value_arg(&value), val, val_size);
if (njs_slow_path(ret != NJS_OK)) {
return ret;
}
} else {
- key_length = njs_max(njs_utf8_length(key, key_size), 0);
- ret = njs_string_new(vm, &name, key, key_size, key_length);
+ ret = njs_vm_value_string_create(vm, njs_value_arg(&name), key,
+ key_size);
if (njs_slow_path(ret != NJS_OK)) {
return ret;
}
if (key_size > 0) {
- ret = njs_function_call(vm, decoder, &njs_value_undefined, &name, 1,
- &name);
+ ret = njs_vm_invoke(vm, decoder, njs_value_arg(&name), 1,
+ njs_value_arg(&name));
if (njs_slow_path(ret != NJS_OK)) {
return ret;
}
- if (!njs_is_string(&name)) {
- njs_value_to_string(vm, &name, &name);
+ if (!njs_value_is_string(njs_value_arg(&name))) {
+ ret = njs_value_to_string(vm, njs_value_arg(&name),
+ njs_value_arg(&name));
+ if (njs_slow_path(ret != NJS_OK)) {
+ return ret;
+ }
}
}
- val_length = njs_max(njs_utf8_length(val, val_size), 0);
- ret = njs_string_new(vm, &value, val, val_size, val_length);
+ ret = njs_vm_value_string_create(vm, njs_value_arg(&value), val,
+ val_size);
if (njs_slow_path(ret != NJS_OK)) {
return ret;
}
if (val_size > 0) {
- ret = njs_function_call(vm, decoder, &njs_value_undefined, &value,
- 1, &value);
+ ret = njs_vm_invoke(vm, decoder, njs_value_arg(&value), 1,
+ njs_value_arg(&value));
if (njs_slow_path(ret != NJS_OK)) {
return ret;
}
- if (!njs_is_string(&value)) {
- njs_value_to_string(vm, &value, &value);
+ if (!njs_value_is_string(njs_value_arg(&value))) {
+ ret = njs_value_to_string(vm, njs_value_arg(&value),
+ njs_value_arg(&value));
+ if (njs_slow_path(ret != NJS_OK)) {
+ return ret;
+ }
}
}
}
- ret = njs_value_property(vm, object, &name, &retval);
+ ret = njs_value_property(vm, object, njs_value_arg(&name),
+ njs_value_arg(&retval));
if (ret == NJS_OK) {
- if (njs_is_array(&retval)) {
- return njs_array_add(vm, njs_array(&retval), &value);
+ if (njs_value_is_array(njs_value_arg(&retval))) {
+ push = njs_vm_array_push(vm, njs_value_arg(&retval));
+ if (njs_slow_path(push == NULL)) {
+ return NJS_ERROR;
+ }
+
+ njs_value_assign(push, njs_value_arg(&value));
+
+ return NJS_OK;
}
- array = njs_array_alloc(vm, 1, 2, 0);
- if (njs_slow_path(array == NULL)) {
+ ret = njs_vm_array_alloc(vm, njs_value_arg(&array), 2);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return ret;
+ }
+
+ push = njs_vm_array_push(vm, njs_value_arg(&array));
+ if (njs_slow_path(push == NULL)) {
return NJS_ERROR;
}
- array->start[0] = retval;
- array->start[1] = value;
+ njs_value_assign(push, njs_value_arg(&retval));
- njs_set_array(&value, array);
+ push = njs_vm_array_push(vm, njs_value_arg(&array));
+ if (njs_slow_path(push == NULL)) {
+ return NJS_ERROR;
+ }
+
+ njs_value_assign(push, njs_value_arg(&value));
+
+ njs_value_assign(&value, &array);
}
- return njs_value_property_set(vm, object, &name, &value);
+ return njs_value_property_set(vm, object, njs_value_arg(&name),
+ njs_value_arg(&value));
}
@@ -384,12 +375,12 @@ static njs_int_t
njs_query_string_parse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
njs_index_t unused, njs_value_t *retval)
{
- int64_t max_keys;
- njs_int_t ret;
- njs_str_t str, sep, eq;
- njs_value_t value, *this, *string, *options, *arg;
- njs_value_t val_sep, val_eq;
- njs_function_t *decode;
+ int64_t max_keys;
+ njs_int_t ret;
+ njs_str_t str, sep, eq;
+ njs_value_t *this, *string, *options, *arg, *val;
+ njs_function_t *decode;
+ njs_opaque_value_t value, val_sep, val_eq;
decode = NULL;
max_keys = 1000;
@@ -397,8 +388,8 @@ njs_query_string_parse(njs_vm_t *vm, njs
this = njs_argument(args, 0);
string = njs_arg(args, nargs, 1);
- if (njs_is_string(string)) {
- njs_string_get(string, &str);
+ if (njs_value_is_string(string)) {
+ njs_value_string_get(string, &str);
} else {
str = njs_str_value("");
@@ -408,71 +399,68 @@ njs_query_string_parse(njs_vm_t *vm, njs
eq = njs_eq_default;
arg = njs_arg(args, nargs, 2);
- if (!njs_is_null_or_undefined(arg)) {
- ret = njs_value_to_string(vm, &val_sep, arg);
+ if (!njs_value_is_null_or_undefined(arg)) {
+ ret = njs_value_to_string(vm, njs_value_arg(&val_sep), arg);
if (njs_slow_path(ret != NJS_OK)) {
return ret;
}
- if (njs_string_length(&val_sep) != 0) {
- njs_string_get(&val_sep, &sep);
+ if (njs_string_length(njs_value_arg(&val_sep)) != 0) {
+ njs_value_string_get(njs_value_arg(&val_sep), &sep);
}
}
arg = njs_arg(args, nargs, 3);
- if (!njs_is_null_or_undefined(arg)) {
- ret = njs_value_to_string(vm, &val_eq, arg);
+ if (!njs_value_is_null_or_undefined(arg)) {
+ ret = njs_value_to_string(vm, njs_value_arg(&val_eq), arg);
if (njs_slow_path(ret != NJS_OK)) {
return ret;
}
- if (njs_string_length(&val_eq) != 0) {
- njs_string_get(&val_eq, &eq);
+ if (njs_string_length(njs_value_arg(&val_eq)) != 0) {
+ njs_value_string_get(njs_value_arg(&val_eq), &eq);
}
}
options = njs_arg(args, nargs, 4);
- if (njs_is_object(options)) {
- ret = njs_value_property(vm, options, njs_value_arg(&njs_max_keys_str),
- &value);
- if (njs_slow_path(ret == NJS_ERROR)) {
- return ret;
- }
-
- ret = njs_value_to_integer(vm, &value, &max_keys);
- if (njs_slow_path(ret != NJS_OK)) {
- return ret;
- }
+ if (njs_value_is_object(options)) {
+ val = njs_vm_object_prop(vm, options, &njs_max_keys_str, &value);
- if (max_keys == 0) {
- max_keys = INT64_MAX;
- }
-
- ret = njs_value_property(vm, options,
- njs_value_arg(&njs_decode_uri_str), &value);
-
- if (ret == NJS_OK) {
- if (njs_slow_path(!njs_is_function(&value))) {
- njs_type_error(vm,
- "option decodeURIComponent is not a function");
+ if (val != NULL) {
+ if (!njs_value_is_valid_number(val)) {
+ njs_vm_error(vm, "is not a number");
return NJS_ERROR;
}
- decode = njs_function(&value);
+ max_keys = njs_value_number(val);
+
+ if (max_keys == 0) {
+ max_keys = INT64_MAX;
+ }
+ }
+
+ val = njs_vm_object_prop(vm, options, &njs_decode_uri_str, &value);
+
+ if (val != NULL) {
+ if (njs_slow_path(!njs_value_is_function(val))) {
+ njs_vm_error(vm, "option decodeURIComponent is not a function");
+ return NJS_ERROR;
+ }
+
+ decode = njs_value_function(val);
}
}
if (decode == NULL) {
- ret = njs_value_property(vm, this, njs_value_arg(&njs_unescape_str),
- &value);
+ val = njs_vm_object_prop(vm, this, &njs_unescape_str, &value);
- if (ret != NJS_OK || !njs_is_function(&value)) {
- njs_type_error(vm, "QueryString.unescape is not a function");
+ if (val == NULL || !njs_value_is_function(val)) {
+ njs_vm_error(vm, "QueryString.unescape is not a function");
return NJS_ERROR;
}
- decode = njs_function(&value);
+ decode = njs_value_function(val);
}
return njs_query_string_parser(vm, str.start, str.start + str.length,
@@ -485,9 +473,7 @@ njs_vm_query_string_parse(njs_vm_t *vm,
njs_value_t *retval)
{
return njs_query_string_parser(vm, start, end, &njs_sep_default,
- &njs_eq_default,
- njs_function(&njs_unescape_default),
- 1000, retval);
+ &njs_eq_default, NULL, 1000, retval);
}
@@ -496,20 +482,16 @@ njs_query_string_parser(njs_vm_t *vm, u_
const njs_str_t *sep, const njs_str_t *eq, njs_function_t *decode,
njs_uint_t max_keys, njs_value_t *retval)
{
- size_t size;
- u_char *part, *key, *val;
- njs_int_t ret;
- njs_uint_t count;
- njs_value_t obj;
- njs_object_t *object;
+ size_t size;
+ u_char *part, *key, *val;
+ njs_int_t ret;
+ njs_uint_t count;
- object = njs_query_string_object_alloc(vm);
- if (njs_slow_path(object == NULL)) {
+ ret = njs_vm_object_alloc(vm, retval, NULL);
+ if (njs_slow_path(ret != NJS_OK)) {
return NJS_ERROR;
}
- njs_set_object(&obj, object);
-
count = 0;
key = query;
@@ -533,7 +515,7 @@ njs_query_string_parser(njs_vm_t *vm, u_
val += eq->length;
}
- ret = njs_query_string_append(vm, &obj, key, size, val, part - val,
+ ret = njs_query_string_append(vm, retval, key, size, val, part - val,
decode);
if (njs_slow_path(ret != NJS_OK)) {
return ret;
@@ -545,8 +527,6 @@ njs_query_string_parser(njs_vm_t *vm, u_
} while (key < end);
- njs_set_object(retval, object);
-
return NJS_OK;
}
@@ -580,7 +560,7 @@ njs_query_string_encode(njs_chb_t *chain
}
if (str->length == 0) {
- return 0;
+ return NJS_OK;
}
p = str->start;
@@ -601,21 +581,26 @@ njs_query_string_encode(njs_chb_t *chain
if (size == str->length) {
memcpy(start, str->start, str->length);
njs_chb_written(chain, str->length);
- return str->length;
+ return NJS_OK;
}
(void) njs_string_encode(escape, str->length, str->start, start);
njs_chb_written(chain, size);
- return size;
+ return NJS_OK;
}
njs_inline njs_bool_t
njs_query_string_is_native_encoder(njs_function_t *encoder)
{
- return encoder->native && encoder->u.native == njs_query_string_escape;
+ njs_opaque_value_t function;
+
+ njs_value_function_set(njs_value_arg(&function), encoder);
+
+ return njs_value_native_function(njs_value_arg(&function))
+ == njs_query_string_escape;
}
@@ -623,11 +608,11 @@ njs_inline njs_int_t
njs_query_string_encoder_call(njs_vm_t *vm, njs_chb_t *chain,
njs_function_t *encoder, njs_value_t *string)
{
- njs_str_t str;
- njs_int_t ret;
- njs_value_t retval;
+ njs_str_t str;
+ njs_int_t ret;
+ njs_opaque_value_t retval;
- if (njs_slow_path(!njs_is_string(string))) {
+ if (njs_slow_path(!njs_value_is_string(string))) {
ret = njs_value_to_string(vm, string, string);
if (njs_slow_path(ret != NJS_OK)) {
return NJS_ERROR;
@@ -635,87 +620,62 @@ njs_query_string_encoder_call(njs_vm_t *
}
if (njs_fast_path(njs_query_string_is_native_encoder(encoder))) {
- njs_string_get(string, &str);
+ njs_value_string_get(string, &str);
return njs_query_string_encode(chain, &str);
}
- ret = njs_function_call(vm, encoder, &njs_value_undefined, string, 1,
- &retval);
+ ret = njs_vm_invoke(vm, encoder, string, 1, njs_value_arg(&retval));
if (njs_slow_path(ret != NJS_OK)) {
- return NJS_ERROR;
+ return ret;
}
- if (njs_slow_path(!njs_is_string(&retval))) {
- ret = njs_value_to_string(vm, &retval, &retval);
+ if (njs_slow_path(!njs_value_is_string(njs_value_arg(&retval)))) {
+ ret = njs_value_to_string(vm, njs_value_arg(&retval),
+ njs_value_arg(&retval));
if (njs_slow_path(ret != NJS_OK)) {
return NJS_ERROR;
}
}
- njs_string_get(&retval, &str);
-
- ret = njs_utf8_length(str.start, str.length);
- if (ret < 0) {
- njs_type_error(vm, "got non-UTF8 string from encoder");
- return NJS_ERROR;
- }
+ njs_value_string_get(njs_value_arg(&retval), &str);
njs_chb_append_str(chain, &str);
- return ret;
+ return NJS_OK;
}
njs_inline njs_int_t
njs_query_string_push(njs_vm_t *vm, njs_chb_t *chain, njs_value_t *key,
- njs_value_t *value, njs_string_prop_t *eq, njs_function_t *encoder)
+ njs_value_t *value, njs_str_t *eq, njs_function_t *encoder)
{
- double num;
- njs_int_t ret, length;
-
- length = 0;
+ njs_int_t ret;
ret = njs_query_string_encoder_call(vm, chain, encoder, key);
- if (njs_slow_path(ret < 0)) {
+ if (njs_slow_path(ret != NJS_OK)) {
return NJS_ERROR;
}
- length += ret;
-
- njs_chb_append(chain, eq->start, eq->size);
- length += eq->length;
+ njs_chb_append(chain, eq->start, eq->length);
- switch (value->type) {
- case NJS_NUMBER:
- num = njs_number(value);
- if (njs_slow_path(isnan(num) || isinf(num))) {
- break;
+ if (njs_value_is_valid_number(value)
+ || njs_value_is_boolean(value)
+ || njs_value_is_string(value))
+ {
+ if (!njs_value_is_string(value)) {
+ ret = njs_value_to_string(vm, value, value);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return NJS_ERROR;
+ }
}
- /* Fall through. */
-
- case NJS_BOOLEAN:
- ret = njs_primitive_value_to_string(vm, value, value);
- if (njs_slow_path(ret != NJS_OK)) {
- return NJS_ERROR;
- }
-
- /* Fall through. */
-
- case NJS_STRING:
ret = njs_query_string_encoder_call(vm, chain, encoder, value);
if (njs_slow_path(ret < 0)) {
return NJS_ERROR;
}
-
- length += ret;
- break;
-
- default:
- break;
}
- return length;
+ return NJS_OK;
}
@@ -723,183 +683,137 @@ static njs_int_t
njs_query_string_stringify(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
njs_index_t unused, njs_value_t *retval)
{
- u_char *p;
- int64_t len;
- ssize_t size;
- uint32_t n, i;
- uint64_t length;
- njs_int_t ret;
- njs_chb_t chain;
- njs_value_t value, result, *string, *this, *object, *arg, *options;
- njs_array_t *keys, *array;
- njs_function_t *encode;
- njs_string_prop_t sep, eq;
-
- njs_value_t val_sep = njs_string("&");
- njs_value_t val_eq = njs_string("=");
-
- (void) njs_string_prop(&sep, &val_sep);
- (void) njs_string_prop(&eq, &val_eq);
+ int64_t len, keys_length;
+ uint32_t n, i;
+ njs_int_t ret;
+ njs_str_t sep, eq;
+ njs_chb_t chain;
+ njs_value_t *this, *object, *arg, *options, *val, *keys;
+ njs_function_t *encode;
+ njs_opaque_value_t value, result, key, *string;
encode = NULL;
+ sep = njs_sep_default;
+ eq = njs_eq_default;
+
this = njs_argument(args, 0);
object = njs_arg(args, nargs, 1);
- if (njs_slow_path(!njs_is_object(object))) {
- njs_value_assign(retval, &njs_string_empty);
+ if (njs_slow_path(!njs_value_is_object(object))) {
+ njs_vm_value_string_set(vm, retval, (u_char *) "", 0);
return NJS_OK;
}
arg = njs_arg(args, nargs, 2);
- if (!njs_is_null_or_undefined(arg)) {
+ if (!njs_value_is_null_or_undefined(arg)) {
ret = njs_value_to_string(vm, arg, arg);
if (njs_slow_path(ret != NJS_OK)) {
return ret;
}
if (njs_string_length(arg) > 0) {
- (void) njs_string_prop(&sep, arg);
+ njs_value_string_get(arg, &sep);
}
}
arg = njs_arg(args, nargs, 3);
- if (!njs_is_null_or_undefined(arg)) {
+ if (!njs_value_is_null_or_undefined(arg)) {
ret = njs_value_to_string(vm, arg, arg);
if (njs_slow_path(ret != NJS_OK)) {
return ret;
}
if (njs_string_length(arg) > 0) {
- (void) njs_string_prop(&eq, arg);
+ njs_value_string_get(arg, &eq);
}
}
options = njs_arg(args, nargs, 4);
- if (njs_is_object(options)) {
- ret = njs_value_property(vm, options,
- njs_value_arg(&njs_encode_uri_str), &value);
+ if (njs_value_is_object(options)) {
+ val = njs_vm_object_prop(vm, options, &njs_encode_uri_str, &value);
- if (ret == NJS_OK) {
- if (njs_slow_path(!njs_is_function(&value))) {
- njs_type_error(vm,
- "option encodeURIComponent is not a function");
+ if (val != NULL) {
+ if (njs_slow_path(!njs_value_is_function(val))) {
+ njs_vm_error(vm, "option encodeURIComponent is not a function");
return NJS_ERROR;
}
- encode = njs_function(&value);
+ encode = njs_value_function(val);
}
}
if (encode == NULL) {
- ret = njs_value_property(vm, this, njs_value_arg(&njs_escape_str),
- &value);
+ val = njs_vm_object_prop(vm, this, &njs_escape_str, &value);
- if (ret != NJS_OK || !njs_is_function(&value)) {
- njs_type_error(vm, "QueryString.escape is not a function");
+ if (val == NULL || !njs_value_is_function(val)) {
+ njs_vm_error(vm, "QueryString.escape is not a function");
return NJS_ERROR;
}
- encode = njs_function(&value);
+ encode = njs_value_function(val);
}
- njs_chb_init(&chain, vm->mem_pool);
+ njs_chb_init(&chain, njs_vm_memory_pool(vm));
- keys = njs_value_own_enumerate(vm, object, NJS_ENUM_KEYS, NJS_ENUM_STRING,
- 0);
+ keys = njs_vm_object_keys(vm, object, njs_value_arg(&value));
if (njs_slow_path(keys == NULL)) {
return NJS_ERROR;
}
- for (n = 0, length = 0; n < keys->length; n++) {
- string = &keys->start[n];
+ (void) njs_vm_array_length(vm, keys, &keys_length);
- ret = njs_value_property(vm, object, string, &value);
+ string = (njs_opaque_value_t *) njs_vm_array_start(vm, keys);
+ if (njs_slow_path(string == NULL)) {
+ return NJS_ERROR;
+ }
+
+ for (n = 0; n < keys_length; n++, string++) {
+ ret = njs_value_property(vm, object, njs_value_arg(string),
+ njs_value_arg(&value));
if (njs_slow_path(ret == NJS_ERROR)) {
goto failed;
}
- if (njs_is_array(&value)) {
-
- if (njs_is_fast_array(&value)) {
- array = njs_array(&value);
-
- for (i = 0; i < array->length; i++) {
- if (chain.last != NULL) {
- njs_chb_append(&chain, sep.start, sep.size);
- length += sep.length;
- }
-
- ret = njs_query_string_push(vm, &chain, string,
- &array->start[i], &eq, encode);
- if (njs_slow_path(ret < 0)) {
- ret = NJS_ERROR;
- goto failed;
- }
-
- length += ret;
- }
-
- continue;
- }
-
- ret = njs_object_length(vm, &value, &len);
- if (njs_slow_path(ret == NJS_ERROR)) {
- goto failed;
- }
+ if (njs_value_is_array(njs_value_arg(&value))) {
+ (void) njs_vm_array_length(vm, njs_value_arg(&value), &len);
for (i = 0; i < len; i++) {
- ret = njs_value_property_i64(vm, &value, i, &result);
+ njs_value_number_set(njs_value_arg(&key), i);
+ ret = njs_value_property(vm, njs_value_arg(&value),
+ njs_value_arg(&key),
+ njs_value_arg(&result));
if (njs_slow_path(ret == NJS_ERROR)) {
goto failed;
}
if (chain.last != NULL) {
- njs_chb_append(&chain, sep.start, sep.size);
- length += sep.length;
+ njs_chb_append(&chain, sep.start, sep.length);
}
- ret = njs_query_string_push(vm, &chain, string, &result, &eq,
+ ret = njs_query_string_push(vm, &chain, njs_value_arg(string),
+ njs_value_arg(&result), &eq,
encode);
- if (njs_slow_path(ret < 0)) {
- ret = NJS_ERROR;
+ if (njs_slow_path(ret != NJS_OK)) {
goto failed;
}
-
- length += ret;
}
continue;
}
if (n != 0) {
- njs_chb_append(&chain, sep.start, sep.size);
- length += sep.length;
+ njs_chb_append(&chain, sep.start, sep.length);
}
- ret = njs_query_string_push(vm, &chain, string, &value, &eq, encode);
- if (njs_slow_path(ret < 0)) {
- ret = NJS_ERROR;
+ ret = njs_query_string_push(vm, &chain, njs_value_arg(string),
+ njs_value_arg(&value), &eq, encode);
+ if (njs_slow_path(ret != NJS_OK)) {
goto failed;
}
-
- length += ret;
}
- size = njs_chb_size(&chain);
- if (njs_slow_path(size < 0)) {
- njs_memory_error(vm);
- return NJS_ERROR;
- }
-
- p = njs_string_alloc(vm, retval, size, length);
- if (njs_slow_path(p == NULL)) {
- return NJS_ERROR;
- }
-
- njs_chb_join_to(&chain, p);
-
- ret = NJS_OK;
+ ret = njs_vm_value_string_create_chb(vm, retval, &chain);
failed:
@@ -913,45 +827,37 @@ static njs_int_t
njs_query_string_escape(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
njs_index_t unused, njs_value_t *retval)
{
- u_char *p;
- ssize_t size, length;
- njs_int_t ret;
- njs_str_t str;
- njs_chb_t chain;
- njs_value_t *string, value;
+ njs_int_t ret;
+ njs_str_t str;
+ njs_chb_t chain;
+ njs_value_t *string;
+ njs_opaque_value_t value;
string = njs_arg(args, nargs, 1);
- if (!njs_is_string(string)) {
- ret = njs_value_to_string(vm, &value, string);
+ if (!njs_value_is_string(string)) {
+ ret = njs_value_to_string(vm, njs_value_arg(&value), string);
if (njs_slow_path(ret != NJS_OK)) {
return ret;
}
- string = &value;
+ string = njs_value_arg(&value);
}
- njs_string_get(string, &str);
+ njs_value_string_get(string, &str);
- njs_chb_init(&chain, vm->mem_pool);
+ njs_chb_init(&chain, njs_vm_memory_pool(vm));
- length = njs_query_string_encode(&chain, &str);
- if (njs_slow_path(length < 0)) {
+ ret = njs_query_string_encode(&chain, &str);
+ if (njs_slow_path(ret != NJS_OK)) {
return NJS_ERROR;
}
- size = njs_chb_size(&chain);
-
- p = njs_string_alloc(vm, retval, size, length);
- if (njs_slow_path(p == NULL)) {
- return NJS_ERROR;
- }
-
- njs_chb_join_to(&chain, p);
+ ret = njs_vm_value_string_create_chb(vm, retval, &chain);
njs_chb_destroy(&chain);
- return NJS_OK;
+ return ret;
}
@@ -959,22 +865,23 @@ static njs_int_t
njs_query_string_unescape(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
njs_index_t unused, njs_value_t *retval)
{
- njs_int_t ret;
- njs_str_t str;
- njs_value_t *string, value;
+ njs_int_t ret;
+ njs_str_t str;
+ njs_value_t *string;
+ njs_opaque_value_t value;
string = njs_arg(args, nargs, 1);
- if (!njs_is_string(string)) {
- ret = njs_value_to_string(vm, &value, string);
+ if (!njs_value_is_string(string)) {
+ ret = njs_value_to_string(vm, njs_value_arg(&value), string);
if (njs_slow_path(ret != NJS_OK)) {
return ret;
}
- string = &value;
+ string = njs_value_arg(&value);
}
- njs_string_get(string, &str);
+ njs_value_string_get(string, &str);
return njs_query_string_decode(vm, retval, str.start, str.length);
}
diff -r b2cbf06ba017 -r fd956d2a25a3 src/njs.h
--- a/src/njs.h Tue May 02 20:50:52 2023 -0700
+++ b/src/njs.h Tue May 02 20:50:55 2023 -0700
@@ -382,6 +382,10 @@ NJS_EXPORT njs_external_ptr_t njs_vm_ext
NJS_EXPORT njs_int_t njs_external_property(njs_vm_t *vm,
njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval,
njs_value_t *retval);
+NJS_EXPORT njs_int_t njs_value_property(njs_vm_t *vm, njs_value_t *value,
+ njs_value_t *key, njs_value_t *retval);
+NJS_EXPORT njs_int_t njs_value_property_set(njs_vm_t *vm, njs_value_t *value,
+ njs_value_t *key, njs_value_t *setval);
NJS_EXPORT uintptr_t njs_vm_meta(njs_vm_t *vm, njs_uint_t index);
NJS_EXPORT njs_function_t *njs_vm_function_alloc(njs_vm_t *vm,
@@ -432,6 +436,8 @@ NJS_EXPORT njs_int_t njs_value_buffer_ge
NJS_EXPORT njs_int_t njs_vm_value_buffer_set(njs_vm_t *vm, njs_value_t *value,
const u_char *start, uint32_t size);
+NJS_EXPORT njs_int_t njs_value_to_string(njs_vm_t *vm, njs_value_t *dst,
+ njs_value_t *value);
/*
* Converts a value to bytes.
*/
@@ -477,6 +483,8 @@ NJS_EXPORT void njs_value_function_set(n
NJS_EXPORT uint8_t njs_value_bool(const njs_value_t *value);
NJS_EXPORT double njs_value_number(const njs_value_t *value);
NJS_EXPORT njs_function_t *njs_value_function(const njs_value_t *value);
+NJS_EXPORT njs_function_native_t njs_value_native_function(
+ const njs_value_t *value);
NJS_EXPORT njs_int_t njs_value_external_tag(const njs_value_t *value);
NJS_EXPORT uint16_t njs_vm_prop_magic16(njs_object_prop_t *prop);
diff -r b2cbf06ba017 -r fd956d2a25a3 src/njs_value.c
--- a/src/njs_value.c Tue May 02 20:50:52 2023 -0700
+++ b/src/njs_value.c Tue May 02 20:50:55 2023 -0700
@@ -487,6 +487,23 @@ njs_value_function(const njs_value_t *va
}
+njs_function_native_t
+njs_value_native_function(const njs_value_t *value)
+{
+ njs_function_t *function;
+
+ if (njs_is_function(value)) {
+ function = njs_function(value);
+
+ if (function->native) {
+ return function->u.native;
+ }
+ }
+
+ return NULL;
+}
More information about the nginx-devel
mailing list