From: hongzhidao Date: Sat, 6 Apr 2019 16:09:09 +0000 (+0800) Subject: Fixed Function.prototype.bind(). X-Git-Tag: 0.3.1~22 X-Git-Url: http://git.kaiwu.me/postgresql/log/contrib/postgres_fdw/static/gitweb.js?a=commitdiff_plain;h=fe146200b2e2c61effb094bb8cc6bcb05e83a349;p=njs.git Fixed Function.prototype.bind(). Making a correct copy of a function. --- diff --git a/njs/njs_function.c b/njs/njs_function.c index 0b07d3c5..7847e78f 100644 --- a/njs/njs_function.c +++ b/njs/njs_function.c @@ -8,6 +8,8 @@ #include +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; diff --git a/njs/test/njs_unit_test.c b/njs/test/njs_unit_test.c index 859479af..fb668e68 100644 --- a/njs/test/njs_unit_test.c +++ b/njs/test/njs_unit_test.c @@ -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 "