[njs] Added Function.prototype.length.

Dmitry Volyntsev xeioex at nginx.com
Mon Aug 27 16:19:57 UTC 2018


details:   http://hg.nginx.org/njs/rev/50dfb4ccbceb
branches:  
changeset: 589:50dfb4ccbceb
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Mon Aug 27 19:19:25 2018 +0300
description:
Added Function.prototype.length.

diffstat:

 njs/njs_function.c           |  36 ++++++++++++++++++++++++++++++++++++
 njs/test/njs_expect_test.exp |   5 +++++
 njs/test/njs_unit_test.c     |  21 +++++++++++++++++++++
 3 files changed, 62 insertions(+), 0 deletions(-)

diffs (99 lines):

diff -r ff2007772ec6 -r 50dfb4ccbceb njs/njs_function.c
--- a/njs/njs_function.c	Mon Aug 27 16:37:42 2018 +0300
+++ b/njs/njs_function.c	Mon Aug 27 19:19:25 2018 +0300
@@ -503,6 +503,36 @@ const njs_object_init_t  njs_function_co
 };
 
 
+/*
+ * ES5.1, 15.3.5.1 length
+ *      the typical number of arguments expected by the function.
+ */
+static njs_ret_t
+njs_function_prototype_length(njs_vm_t *vm, njs_value_t *value,
+    njs_value_t *setval, njs_value_t *retval)
+{
+    nxt_uint_t      n;
+    njs_function_t  *function;
+
+    function = value->data.u.function;
+
+    if (function->native) {
+        for (n = function->args_offset; n <= NJS_ARGS_TYPES_MAX; n++) {
+            if (function->args_types[n] == 0) {
+                break;
+            }
+        }
+
+    } else {
+        n = function->u.lambda->nargs + 1;
+    }
+
+    njs_value_number_set(retval, n - function->args_offset);
+
+    return NXT_OK;
+}
+
+
 static njs_ret_t
 njs_function_prototype_call(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
     njs_index_t retval)
@@ -671,6 +701,12 @@ njs_function_prototype_bind(njs_vm_t *vm
 static const njs_object_prop_t  njs_function_prototype_properties[] =
 {
     {
+        .type = NJS_PROPERTY_HANDLER,
+        .name = njs_string("length"),
+        .value = njs_prop_handler(njs_function_prototype_length),
+    },
+
+    {
         .type = NJS_METHOD,
         .name = njs_string("call"),
         .value = njs_native_function(njs_function_prototype_call, 0, 0),
diff -r ff2007772ec6 -r 50dfb4ccbceb njs/test/njs_expect_test.exp
--- a/njs/test/njs_expect_test.exp	Mon Aug 27 16:37:42 2018 +0300
+++ b/njs/test/njs_expect_test.exp	Mon Aug 27 19:19:25 2018 +0300
@@ -183,6 +183,11 @@ njs_test {
 }
 
 njs_test {
+    {"console.log.length\r\n"
+     "console.log.length\r\n0"}
+}
+
+njs_test {
     {"var print = console.log.bind(console); print(1, 'a', [1, 2])\r\n"
      "1 'a' \\\[1,2]\r\nundefined\r\n>> "}
     {"var print = console.dump.bind(console); print(1, 'a', [1, 2])\r\n"
diff -r ff2007772ec6 -r 50dfb4ccbceb njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c	Mon Aug 27 16:37:42 2018 +0300
+++ b/njs/test/njs_unit_test.c	Mon Aug 27 19:19:25 2018 +0300
@@ -4833,6 +4833,27 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("function f() { }"),
       nxt_string("undefined") },
 
+    { nxt_string("function f() { }; f.length"),
+      nxt_string("0") },
+
+    { nxt_string("function f() { }; f.length = 1"),
+      nxt_string("TypeError: Cannot assign to read-only property 'length' of function") },
+
+    { nxt_string("function f(a,b) { }; f.length"),
+      nxt_string("2") },
+
+    { nxt_string("function f(a,b) { }; var ff = f.bind(f, 1); ff.length"),
+      nxt_string("1") },
+
+    { nxt_string("JSON.parse.length"),
+      nxt_string("2") },
+
+    { nxt_string("JSON.parse.bind(JSON, '[]').length"),
+      nxt_string("1") },
+
+    { nxt_string("var o = {}; o.hasOwnProperty.length"),
+      nxt_string("1") },
+
     { nxt_string("var x; function f() { }"),
       nxt_string("undefined") },
 


More information about the nginx-devel mailing list