[njs] Fixed Function.prototype.bind().
Dmitry Volyntsev
xeioex at nginx.com
Sat Apr 6 17:51:06 UTC 2019
details: https://hg.nginx.org/njs/rev/84cb61f23b7e
branches:
changeset: 873:84cb61f23b7e
user: hongzhidao <hongzhidao at gmail.com>
date: Sun Apr 07 00:09:09 2019 +0800
description:
Fixed Function.prototype.bind().
Making a correct copy of a function.
diffstat:
njs/njs_function.c | 33 ++++++++++++++++++++++-----------
njs/test/njs_unit_test.c | 10 ++++++++++
2 files changed, 32 insertions(+), 11 deletions(-)
diffs (96 lines):
diff -r 7dba758fda64 -r 84cb61f23b7e njs/njs_function.c
--- a/njs/njs_function.c Fri Apr 05 17:49:22 2019 +0300
+++ b/njs/njs_function.c Sun Apr 07 00:09:09 2019 +0800
@@ -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, nj
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, nj
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
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;
diff -r 7dba758fda64 -r 84cb61f23b7e njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c Fri Apr 05 17:49:22 2019 +0300
+++ b/njs/test/njs_unit_test.c Sun Apr 07 00:09:09 2019 +0800
@@ -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 "
More information about the nginx-devel
mailing list