Modules: added support for Buffer object where string is expected.
diff --git a/nginx/ngx_http_js_module.c b/nginx/ngx_http_js_module.c
index 8685be8..68a4bf8 100644
--- a/nginx/ngx_http_js_module.c
+++ b/nginx/ngx_http_js_module.c
@@ -2371,7 +2371,7 @@
     arg = njs_arg(args, nargs, 2);
 
     if (njs_value_is_string(arg)) {
-        if (njs_vm_value_to_string(vm, &args_arg, arg) != NJS_OK) {
+        if (ngx_js_string(vm, arg, &args_arg) != NJS_OK) {
             njs_vm_error(vm, "failed to convert args");
             return NJS_ERROR;
         }
diff --git a/nginx/ngx_js.c b/nginx/ngx_js.c
index 03c7877..976f3b7 100644
--- a/nginx/ngx_js.c
+++ b/nginx/ngx_js.c
@@ -105,7 +105,7 @@
 ngx_js_string(njs_vm_t *vm, njs_value_t *value, njs_str_t *str)
 {
     if (value != NULL && !njs_value_is_null_or_undefined(value)) {
-        if (njs_vm_value_to_string(vm, str, value) == NJS_ERROR) {
+        if (njs_vm_value_to_bytes(vm, str, value) == NJS_ERROR) {
             return NGX_ERROR;
         }
 
diff --git a/nginx/ngx_stream_js_module.c b/nginx/ngx_stream_js_module.c
index 29742dc..63b0e5d 100644
--- a/nginx/ngx_stream_js_module.c
+++ b/nginx/ngx_stream_js_module.c
@@ -942,9 +942,7 @@
         return NJS_ERROR;
     }
 
-    if (njs_vm_value_to_string(vm, &name, njs_arg(args, nargs, 1))
-        == NJS_ERROR)
-    {
+    if (ngx_js_string(vm, njs_arg(args, nargs, 1), &name) == NJS_ERROR) {
         njs_vm_error(vm, "failed to convert event arg");
         return NJS_ERROR;
     }
@@ -991,9 +989,7 @@
         return NJS_ERROR;
     }
 
-    if (njs_vm_value_to_string(vm, &name, njs_arg(args, nargs, 1))
-        == NJS_ERROR)
-    {
+    if (ngx_js_string(vm, njs_arg(args, nargs, 1), &name) == NJS_ERROR) {
         njs_vm_error(vm, "failed to convert event arg");
         return NJS_ERROR;
     }
diff --git a/src/njs.h b/src/njs.h
index 00d4e0e..cf63f21 100644
--- a/src/njs.h
+++ b/src/njs.h
@@ -339,6 +339,12 @@
     const u_char *start, uint32_t size);
 
 /*
+ * Converts a value to bytes.
+ */
+NJS_EXPORT njs_int_t njs_vm_value_to_bytes(njs_vm_t *vm, njs_str_t *dst,
+    njs_value_t *src);
+
+/*
  * Converts a value to string.
  */
 NJS_EXPORT njs_int_t njs_vm_value_to_string(njs_vm_t *vm, njs_str_t *dst,
diff --git a/src/njs_vm.c b/src/njs_vm.c
index de85bc9..5658727 100644
--- a/src/njs_vm.c
+++ b/src/njs_vm.c
@@ -1116,6 +1116,67 @@
 
 
 njs_int_t
+njs_vm_value_to_bytes(njs_vm_t *vm, njs_str_t *dst, njs_value_t *src)
+{
+    u_char              *start;
+    size_t              size;
+    njs_int_t           ret;
+    njs_value_t         value;
+    njs_typed_array_t   *array;
+    njs_array_buffer_t  *buffer;
+
+    if (njs_slow_path(src == NULL)) {
+        return NJS_ERROR;
+    }
+
+    ret = NJS_OK;
+    value = *src;
+
+    switch (value.type) {
+    case NJS_TYPED_ARRAY:
+    case NJS_DATA_VIEW:
+        array = njs_typed_array(&value);
+        buffer = njs_typed_array_buffer(array);
+        if (njs_slow_path(njs_is_detached_buffer(buffer))) {
+            njs_type_error(vm, "detached buffer");
+            return NJS_ERROR;
+        }
+
+        dst->start = &buffer->u.u8[array->offset];
+        dst->length = array->byte_length;
+        break;
+
+    default:
+        ret = njs_value_to_string(vm, &value, &value);
+        if (njs_slow_path(ret != NJS_OK)) {
+            return NJS_ERROR;
+        }
+
+        size = value.short_string.size;
+
+        if (size != NJS_STRING_LONG) {
+            start = njs_mp_alloc(vm->mem_pool, size);
+            if (njs_slow_path(start == NULL)) {
+                njs_memory_error(vm);
+                return NJS_ERROR;
+            }
+
+            memcpy(start, value.short_string.start, size);
+
+        } else {
+            size = value.long_string.size;
+            start = value.long_string.data->start;
+        }
+
+        dst->length = size;
+        dst->start = start;
+    }
+
+    return ret;
+}
+
+
+njs_int_t
 njs_vm_value_string_copy(njs_vm_t *vm, njs_str_t *retval,
     njs_value_t *value, uintptr_t *next)
 {
diff --git a/src/test/njs_externals_test.c b/src/test/njs_externals_test.c
index 9787be3..cdb89da 100644
--- a/src/test/njs_externals_test.c
+++ b/src/test/njs_externals_test.c
@@ -130,7 +130,7 @@
     field = (njs_str_t *) (p + njs_vm_prop_magic32(prop));
 
     if (setval != NULL) {
-        return njs_vm_value_to_string(vm, field, setval);
+        return njs_vm_value_to_bytes(vm, field, setval);
     }
 
     return njs_vm_value_string_set(vm, retval, field->start, field->length);
@@ -358,7 +358,7 @@
         return NJS_ERROR;
     }
 
-    ret = njs_vm_value_to_string(vm, &s, njs_arg(args, nargs, 1));
+    ret = njs_vm_value_to_bytes(vm, &s, njs_arg(args, nargs, 1));
     if (ret == NJS_OK && s.length == 3 && memcmp(s.start, "YES", 3) == 0) {
         return njs_vm_value_string_set(vm, njs_vm_retval(vm), r->uri.start,
                                        r->uri.length);
@@ -388,7 +388,7 @@
         goto memory_error;
     }
 
-    if (njs_vm_value_to_string(vm, &sr->uri, njs_arg(args, nargs, 1))
+    if (njs_vm_value_to_bytes(vm, &sr->uri, njs_arg(args, nargs, 1))
         != NJS_OK)
     {
         return NJS_ERROR;
@@ -424,7 +424,7 @@
         return NJS_ERROR;
     }
 
-    if (njs_vm_value_to_string(vm, &name, njs_arg(args, nargs, 1)) != NJS_OK) {
+    if (njs_vm_value_to_bytes(vm, &name, njs_arg(args, nargs, 1)) != NJS_OK) {
         return NJS_ERROR;
     }