]> git.kaiwu.me - njs.git/commitdiff
Fixed Function.prototype.bind().
authorhongzhidao <hongzhidao@gmail.com>
Sat, 6 Apr 2019 16:09:09 +0000 (00:09 +0800)
committerhongzhidao <hongzhidao@gmail.com>
Sat, 6 Apr 2019 16:09:09 +0000 (00:09 +0800)
Making a correct copy of a function.

njs/njs_function.c
njs/test/njs_unit_test.c

index 0b07d3c5a7305647bd71bf5ddc2eb529b41fd8c7..7847e78f46b5809981c6328c1ef036b9858826ab 100644 (file)
@@ -8,6 +8,8 @@
 #include <string.h>
 
 
+static njs_function_t *njs_function_copy(njs_vm_t *vm,
+    const njs_function_t *function);
 static njs_native_frame_t *njs_function_frame_alloc(njs_vm_t *vm, size_t size);
 static njs_ret_t njs_normalize_args(njs_vm_t *vm, njs_value_t *args,
     uint8_t *args_types, nxt_uint_t nargs);
@@ -71,8 +73,6 @@ fail:
 njs_function_t *
 njs_function_value_copy(njs_vm_t *vm, njs_value_t *value)
 {
-    size_t          size;
-    nxt_uint_t      n, nesting;
     njs_function_t  *function, *copy;
 
     function = value->data.u.function;
@@ -81,6 +81,25 @@ njs_function_value_copy(njs_vm_t *vm, njs_value_t *value)
         return function;
     }
 
+    copy = njs_function_copy(vm, function);
+    if (nxt_slow_path(copy == NULL)) {
+        njs_memory_error(vm);
+        return NULL;
+    }
+
+    value->data.u.function = copy;
+
+    return copy;
+}
+
+
+static njs_function_t *
+njs_function_copy(njs_vm_t *vm, const njs_function_t *function)
+{
+    size_t          size;
+    nxt_uint_t      n, nesting;
+    njs_function_t  *copy;
+
     nesting = (function->native) ? 0 : function->u.lambda->nesting;
 
     size = sizeof(njs_function_t) + nesting * sizeof(njs_closure_t *);
@@ -91,8 +110,6 @@ njs_function_value_copy(njs_vm_t *vm, njs_value_t *value)
         return NULL;
     }
 
-    value->data.u.function = copy;
-
     *copy = *function;
     copy->object.__proto__ = &vm->prototypes[NJS_PROTOTYPE_FUNCTION].object;
     copy->object.shared = 0;
@@ -1050,18 +1067,12 @@ njs_function_prototype_bind(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs,
         return NXT_ERROR;
     }
 
-    function = nxt_mp_alloc(vm->mem_pool, sizeof(njs_function_t));
+    function = njs_function_copy(vm, args[0].data.u.function);
     if (nxt_slow_path(function == NULL)) {
         njs_memory_error(vm);
         return NXT_ERROR;
     }
 
-    *function = *args[0].data.u.function;
-
-    function->object.__proto__ = &vm->prototypes[NJS_PROTOTYPE_FUNCTION].object;
-    function->object.shared = 0;
-    function->object.extensible = 1;
-
     if (nargs == 1) {
         args = (njs_value_t *) &njs_value_undefined;
 
index 859479af12b671a894677066b3aa8136aba48c06..fb668e6879ca3cc3b800f7f552dca86f20235f41 100644 (file)
@@ -6356,6 +6356,16 @@ static njs_unit_test_t  njs_test[] =
                  "var b = f.bind('1', '2', '3'); b.apply()"),
       nxt_string("123") },
 
+    { nxt_string("function f() { var a; return (function() { a = 1; return a; }).bind()() } f()"),
+      nxt_string("1") },
+
+    { nxt_string("function f() { var a; function baz() { a = 1; return a; } return baz.bind()(); } f()"),
+      nxt_string("1") },
+
+    { nxt_string("function f(a, b) { return a + b }"
+                 "f(3,4) === f.bind()(3,4)"),
+      nxt_string("true") },
+
     { nxt_string("var obj = {prop:'abc'}; "
                  "var func = function(x) { "
                  "    return this === obj && x === 1 && arguments[0] === 1 "