From: Dmitry Volyntsev Date: Fri, 3 Apr 2020 16:10:00 +0000 (+0000) Subject: Added API for working with arrays. X-Git-Tag: 0.4.0~14 X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=8da87fc2219c3632e14556bd7e413a844001b415;p=njs.git Added API for working with arrays. --- diff --git a/nginx/ngx_http_js_module.c b/nginx/ngx_http_js_module.c index 1db43ed9..49ef5efe 100644 --- a/nginx/ngx_http_js_module.c +++ b/nginx/ngx_http_js_module.c @@ -1806,6 +1806,7 @@ ngx_http_js_ext_subrequest(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_value_t *value, *arg, *options; njs_function_t *callback; ngx_http_js_ctx_t *ctx; + njs_opaque_value_t lvalue; ngx_http_request_t *r, *sr; ngx_http_request_body_t *rb; @@ -1891,7 +1892,7 @@ ngx_http_js_ext_subrequest(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } if (options != NULL) { - value = njs_vm_object_prop(vm, options, &args_key); + value = njs_vm_object_prop(vm, options, &args_key, &lvalue); if (value != NULL) { if (ngx_http_js_string(vm, value, &args_arg) != NJS_OK) { njs_vm_error(vm, "failed to convert options.args"); @@ -1899,12 +1900,12 @@ ngx_http_js_ext_subrequest(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } } - value = njs_vm_object_prop(vm, options, &detached_key); + value = njs_vm_object_prop(vm, options, &detached_key, &lvalue); if (value != NULL) { detached = njs_value_bool(value); } - value = njs_vm_object_prop(vm, options, &method_key); + value = njs_vm_object_prop(vm, options, &method_key, &lvalue); if (value != NULL) { if (ngx_http_js_string(vm, value, &method_name) != NJS_OK) { njs_vm_error(vm, "failed to convert options.method"); @@ -1924,7 +1925,7 @@ ngx_http_js_ext_subrequest(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } } - value = njs_vm_object_prop(vm, options, &body_key); + value = njs_vm_object_prop(vm, options, &body_key, &lvalue); if (value != NULL) { if (ngx_http_js_string(vm, value, &body_arg) != NJS_OK) { njs_vm_error(vm, "failed to convert options.body"); diff --git a/nginx/ngx_stream_js_module.c b/nginx/ngx_stream_js_module.c index 3b81a1af..f9b12e5e 100644 --- a/nginx/ngx_stream_js_module.c +++ b/nginx/ngx_stream_js_module.c @@ -1064,6 +1064,7 @@ ngx_stream_js_ext_send(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_value_t *flags, *value; ngx_chain_t *cl; ngx_connection_t *c; + njs_opaque_value_t lvalue; ngx_stream_js_ctx_t *ctx; ngx_stream_session_t *s; @@ -1096,12 +1097,12 @@ ngx_stream_js_ext_send(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, flags = njs_arg(args, nargs, 2); if (njs_value_is_object(flags)) { - value = njs_vm_object_prop(vm, flags, &flush_key); + value = njs_vm_object_prop(vm, flags, &flush_key, &lvalue); if (value != NULL) { flush = njs_value_bool(value); } - value = njs_vm_object_prop(vm, flags, &last_key); + value = njs_vm_object_prop(vm, flags, &last_key, &lvalue); if (value != NULL) { last_buf = njs_value_bool(value); } diff --git a/src/njs.h b/src/njs.h index 7953d2f3..cc750642 100644 --- a/src/njs.h +++ b/src/njs.h @@ -356,15 +356,21 @@ NJS_EXPORT njs_int_t njs_value_is_number(const njs_value_t *value); NJS_EXPORT njs_int_t njs_value_is_valid_number(const njs_value_t *value); NJS_EXPORT njs_int_t njs_value_is_string(const njs_value_t *value); NJS_EXPORT njs_int_t njs_value_is_object(const njs_value_t *value); +NJS_EXPORT njs_int_t njs_value_is_array(const njs_value_t *value); NJS_EXPORT njs_int_t njs_value_is_function(const njs_value_t *value); NJS_EXPORT njs_int_t njs_vm_object_alloc(njs_vm_t *vm, njs_value_t *retval, ...); NJS_EXPORT njs_value_t *njs_vm_object_prop(njs_vm_t *vm, - const njs_value_t *value, const njs_str_t *key); + njs_value_t *value, const njs_str_t *key, njs_opaque_value_t *retval); NJS_EXPORT njs_int_t njs_vm_array_alloc(njs_vm_t *vm, njs_value_t *retval, uint32_t spare); +NJS_EXPORT njs_int_t njs_vm_array_length(njs_vm_t *vm, njs_value_t *value, + int64_t *length); +NJS_EXPORT njs_value_t *njs_vm_array_start(njs_vm_t *vm, njs_value_t *value); +NJS_EXPORT njs_value_t *njs_vm_array_prop(njs_vm_t *vm, + njs_value_t *value, int64_t index, njs_opaque_value_t *retval); NJS_EXPORT njs_value_t *njs_vm_array_push(njs_vm_t *vm, njs_value_t *value); NJS_EXPORT njs_int_t njs_vm_json_parse(njs_vm_t *vm, njs_value_t *args, diff --git a/src/njs_value.c b/src/njs_value.c index 40c9125c..89b64ff8 100644 --- a/src/njs_value.c +++ b/src/njs_value.c @@ -464,6 +464,13 @@ njs_value_is_object(const njs_value_t *value) } +njs_int_t +njs_value_is_array(const njs_value_t *value) +{ + return njs_is_array(value); +} + + njs_int_t njs_value_is_function(const njs_value_t *value) { diff --git a/src/njs_vm.c b/src/njs_vm.c index 9857ffdd..2827ad46 100644 --- a/src/njs_vm.c +++ b/src/njs_vm.c @@ -826,7 +826,7 @@ njs_vm_array_alloc(njs_vm_t *vm, njs_value_t *retval, uint32_t spare) { njs_array_t *array; - array = njs_array_alloc(vm, 0, 0, spare); + array = njs_array_alloc(vm, 1, 0, spare); if (njs_slow_path(array == NULL)) { return NJS_ERROR; @@ -861,28 +861,82 @@ njs_vm_array_push(njs_vm_t *vm, njs_value_t *value) njs_value_t * -njs_vm_object_prop(njs_vm_t *vm, const njs_value_t *value, const njs_str_t *key) +njs_vm_object_prop(njs_vm_t *vm, njs_value_t *value, const njs_str_t *prop, + njs_opaque_value_t *retval) { - njs_int_t ret; - njs_object_prop_t *prop; - njs_lvlhsh_query_t lhq; + njs_int_t ret; + njs_value_t key; if (njs_slow_path(!njs_is_object(value))) { + njs_type_error(vm, "njs_vm_object_prop() argument is not object"); return NULL; } - lhq.key = *key; - lhq.key_hash = njs_djb_hash(lhq.key.start, lhq.key.length); - lhq.proto = &njs_object_hash_proto; + ret = njs_vm_value_string_set(vm, &key, prop->start, prop->length); + if (njs_slow_path(ret != NJS_OK)) { + return NULL; + } + + ret = njs_value_property(vm, value, &key, njs_value_arg(retval)); + if (njs_slow_path(ret != NJS_OK)) { + return NULL; + } + + return njs_value_arg(retval); +} + + +njs_value_t * +njs_vm_array_prop(njs_vm_t *vm, njs_value_t *value, int64_t index, + njs_opaque_value_t *retval) +{ + njs_int_t ret; + njs_array_t *array; + + if (njs_slow_path(!njs_is_object(value))) { + njs_type_error(vm, "njs_vm_array_prop() argument is not object"); + return NULL; + } + + if (njs_fast_path(njs_is_fast_array(value))) { + array = njs_array(value); + + if (index >= 0 && index < array->length) { + return &array->start[index]; + } - ret = njs_lvlhsh_find(njs_object_hash(value), &lhq); + return NULL; + } + + ret = njs_value_property_i64(vm, value, index, njs_value_arg(retval)); if (njs_slow_path(ret != NJS_OK)) { return NULL; } - prop = lhq.value; + return njs_value_arg(retval); +} + + +njs_value_t * +njs_vm_array_start(njs_vm_t *vm, njs_value_t *value) +{ + if (njs_slow_path(!njs_is_fast_array(value))) { + njs_type_error(vm, "njs_vm_array_start() argument is not a fast array"); + return NULL; + } + + return njs_array(value)->start; +} + + +njs_int_t +njs_vm_array_length(njs_vm_t *vm, njs_value_t *value, int64_t *length) +{ + if (njs_fast_path(njs_is_array(value))) { + *length = njs_array(value)->length; + } - return &prop->value; + return njs_object_length(vm, value, length); }