]> git.kaiwu.me - njs.git/commitdiff
Added API for working with arrays.
authorDmitry Volyntsev <xeioex@nginx.com>
Fri, 3 Apr 2020 16:10:00 +0000 (16:10 +0000)
committerDmitry Volyntsev <xeioex@nginx.com>
Fri, 3 Apr 2020 16:10:00 +0000 (16:10 +0000)
nginx/ngx_http_js_module.c
nginx/ngx_stream_js_module.c
src/njs.h
src/njs_value.c
src/njs_vm.c

index 1db43ed92717ee035cba7d5f50b27e1a47ff0a6e..49ef5efe4493d27a517ce5e4332d1949acb4b762 100644 (file)
@@ -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");
index 3b81a1afd289c53b6947064e87d808aaf0864e8c..f9b12e5e6832e5e150ec6fdd893e1e8f63f761ec 100644 (file)
@@ -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);
         }
index 7953d2f3173a4b090e950d56ba20d9eb9cf7b169..cc750642c0a50ea5816697dac37496bd19fce4a8 100644 (file)
--- 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,
index 40c9125ce4cb0b00687521dd31ea518cc40187be..89b64ff830fedf5b4d236bd4235928e183f8f0c7 100644 (file)
@@ -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)
 {
index 9857ffdd01fb219464130d1ba757fa080dfb03e4..2827ad46fc3e9541677330be5465c6e587452567 100644 (file)
@@ -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);
 }