[njs] Added API for working with arrays.

Dmitry Volyntsev xeioex at nginx.com
Fri Apr 3 16:10:47 UTC 2020


details:   https://hg.nginx.org/njs/rev/9812e7d99e7c
branches:  
changeset: 1366:9812e7d99e7c
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Fri Apr 03 16:10:00 2020 +0000
description:
Added API for working with arrays.

diffstat:

 nginx/ngx_http_js_module.c   |   9 ++--
 nginx/ngx_stream_js_module.c |   5 +-
 src/njs.h                    |   8 ++++-
 src/njs_value.c              |   7 ++++
 src/njs_vm.c                 |  76 +++++++++++++++++++++++++++++++++++++------
 5 files changed, 87 insertions(+), 18 deletions(-)

diffs (218 lines):

diff -r 78b8cfd5b1e9 -r 9812e7d99e7c nginx/ngx_http_js_module.c
--- a/nginx/ngx_http_js_module.c	Fri Apr 03 16:06:55 2020 +0000
+++ b/nginx/ngx_http_js_module.c	Fri Apr 03 16:10:00 2020 +0000
@@ -1806,6 +1806,7 @@ ngx_http_js_ext_subrequest(njs_vm_t *vm,
     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,
     }
 
     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,
             }
         }
 
-        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,
             }
         }
 
-        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 -r 78b8cfd5b1e9 -r 9812e7d99e7c nginx/ngx_stream_js_module.c
--- a/nginx/ngx_stream_js_module.c	Fri Apr 03 16:06:55 2020 +0000
+++ b/nginx/ngx_stream_js_module.c	Fri Apr 03 16:10:00 2020 +0000
@@ -1064,6 +1064,7 @@ ngx_stream_js_ext_send(njs_vm_t *vm, njs
     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
     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 -r 78b8cfd5b1e9 -r 9812e7d99e7c src/njs.h
--- a/src/njs.h	Fri Apr 03 16:06:55 2020 +0000
+++ b/src/njs.h	Fri Apr 03 16:10:00 2020 +0000
@@ -356,15 +356,21 @@ NJS_EXPORT njs_int_t njs_value_is_number
 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 -r 78b8cfd5b1e9 -r 9812e7d99e7c src/njs_value.c
--- a/src/njs_value.c	Fri Apr 03 16:06:55 2020 +0000
+++ b/src/njs_value.c	Fri Apr 03 16:10:00 2020 +0000
@@ -465,6 +465,13 @@ njs_value_is_object(const njs_value_t *v
 
 
 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)
 {
     return njs_is_function(value);
diff -r 78b8cfd5b1e9 -r 9812e7d99e7c src/njs_vm.c
--- a/src/njs_vm.c	Fri Apr 03 16:06:55 2020 +0000
+++ b/src/njs_vm.c	Fri Apr 03 16:10:00 2020 +0000
@@ -826,7 +826,7 @@ njs_vm_array_alloc(njs_vm_t *vm, njs_val
 {
     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_valu
 
 
 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_lvlhsh_find(njs_object_hash(value), &lhq);
+    ret = njs_value_property(vm, value, &key, 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_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];
+        }
+
+        return NULL;
+    }
 
-    return &prop->value;
+    ret = njs_value_property_i64(vm, value, index, njs_value_arg(retval));
+    if (njs_slow_path(ret != NJS_OK)) {
+        return NULL;
+    }
+
+    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 njs_object_length(vm, value, length);
 }
 
 


More information about the nginx-devel mailing list