]> git.kaiwu.me - njs.git/commitdiff
Added Function.prototype.length.
authorDmitry Volyntsev <xeioex@nginx.com>
Mon, 27 Aug 2018 16:19:25 +0000 (19:19 +0300)
committerDmitry Volyntsev <xeioex@nginx.com>
Mon, 27 Aug 2018 16:19:25 +0000 (19:19 +0300)
njs/njs_function.c
njs/test/njs_expect_test.exp
njs/test/njs_unit_test.c

index 2b18a883ce45aa2cb28b6d3d4a473814f2ec19e3..7aa5773e78d4aa64de3c8724fc53b4581801cd98 100644 (file)
@@ -503,6 +503,36 @@ const njs_object_init_t  njs_function_constructor_init = {
 };
 
 
+/*
+ * 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)
@@ -670,6 +700,12 @@ njs_function_prototype_bind(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
 
 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"),
index 075fb419330ddb14d74ddba55a28f3ac3f7071b3..188787890d339cdd2e11286c32a10b759ca4bda1 100644 (file)
@@ -182,6 +182,11 @@ njs_test {
      "console.ll()\r\nTypeError: cannot find property 'll' of an external object"}
 }
 
+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>> "}
index 110ac75025fe476599d543964e26a6313d129d38..1629f9ed76752ac95876384cb3aa5a2b2d756470 100644 (file)
@@ -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") },