[njs] Initializing closure values of a function.
Dmitry Volyntsev
xeioex at nginx.com
Tue Nov 6 17:58:14 UTC 2018
details: http://hg.nginx.org/njs/rev/0372810c0d98
branches:
changeset: 639:0372810c0d98
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Tue Nov 06 20:57:53 2018 +0300
description:
Initializing closure values of a function.
This fixes #55 issue on Github.
diffstat:
njs/njs_function.c | 10 +++++-----
njs/njs_function.h | 1 +
njs/njs_generator.c | 4 +++-
njs/test/njs_unit_test.c | 40 ++++++++++++++++++++++++++++++++++++++++
4 files changed, 49 insertions(+), 6 deletions(-)
diffs (110 lines):
diff -r 5766e459c203 -r 0372810c0d98 njs/njs_function.c
--- a/njs/njs_function.c Tue Nov 06 20:57:52 2018 +0300
+++ b/njs/njs_function.c Tue Nov 06 20:57:53 2018 +0300
@@ -399,7 +399,7 @@ njs_function_call(njs_vm_t *vm, njs_inde
njs_ret_t ret;
nxt_uint_t n, nesting;
njs_frame_t *frame;
- njs_value_t *value;
+ njs_value_t *dst, *src;
njs_closure_t *closure, **closures;
njs_function_t *function;
njs_function_lambda_t *lambda;
@@ -459,14 +459,14 @@ njs_function_call(njs_vm_t *vm, njs_inde
return NXT_ERROR;
}
- /* TODO: copy initialzed values. */
-
size -= sizeof(njs_value_t);
closure->u.count = 0;
- value = closure->values;
+ dst = closure->values;
+
+ src = lambda->closure_scope;
do {
- *value++ = njs_value_void;
+ *dst++ = *src++;
size -= sizeof(njs_value_t);
} while (size != 0);
}
diff -r 5766e459c203 -r 0372810c0d98 njs/njs_function.h
--- a/njs/njs_function.h Tue Nov 06 20:57:52 2018 +0300
+++ b/njs/njs_function.h Tue Nov 06 20:57:53 2018 +0300
@@ -34,6 +34,7 @@ struct njs_function_lambda_s {
/* Initial values of local scope. */
njs_value_t *local_scope;
+ njs_value_t *closure_scope;
union {
u_char *start;
diff -r 5766e459c203 -r 0372810c0d98 njs/njs_generator.c
--- a/njs/njs_generator.c Tue Nov 06 20:57:52 2018 +0300
+++ b/njs/njs_generator.c Tue Nov 06 20:57:53 2018 +0300
@@ -2047,11 +2047,13 @@ njs_generate_function_scope(njs_vm_t *vm
if (closure != NULL) {
lambda->block_closures = 1;
+ lambda->closure_scope = closure->start;
size = (1 + closure->items) * sizeof(njs_value_t);
}
+ lambda->closure_size = size;
+
lambda->nesting = node->scope->nesting;
- lambda->closure_size = size;
lambda->arguments_object = parser->arguments_object;
lambda->local_size = parser->scope_size;
diff -r 5766e459c203 -r 0372810c0d98 njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c Tue Nov 06 20:57:52 2018 +0300
+++ b/njs/test/njs_unit_test.c Tue Nov 06 20:57:53 2018 +0300
@@ -5287,6 +5287,46 @@ static njs_unit_test_t njs_test[] =
{ nxt_string("function f() { var a = f2(); }"),
nxt_string("ReferenceError: \"f2\" is not defined in 1") },
+ { nxt_string("(function(){ function f() {return f}; return f()})()"),
+ nxt_string("[object Function]") },
+
+ { nxt_string("var a = ''; "
+ "function f(list) {"
+ " function add(v) {a+=v};"
+ " list.forEach(function(v) {add(v)});"
+ "};"
+ "f(['a', 'b', 'c']); a"),
+ nxt_string("abc") },
+
+ { nxt_string("var l = [];"
+ "var f = function() { "
+ " function f2() { l.push(f); l.push(f2); }; "
+ " l.push(f); l.push(f2); "
+ " f2(); "
+ "}; "
+ "f(); "
+ "l.every(function(v) {return typeof v == 'function'})"),
+ nxt_string("true") },
+
+ { nxt_string("var l = [];"
+ "function baz() {"
+ " function foo(v) {"
+ " function bar() { foo(0); }"
+ " l.push(v);"
+ " if (v === 1) { bar(); }"
+ " }"
+ " foo(1);"
+ "}; baz(); l"),
+ nxt_string("1,0") },
+
+ { nxt_string("var gen = (function(){ "
+ " var s = 0; "
+ " return { inc: function() {s++}, "
+ " s: function() {return s} };});"
+ "var o1 = gen(); var o2 = gen();"
+ "[o1.s(),o2.s(),o1.inc(),o1.s(),o2.s(),o2.inc(),o1.s(),o2.s()]"),
+ nxt_string("0,0,,1,0,,1,1") },
+
/* Recursive fibonacci. */
{ nxt_string("function fibo(n) {"
More information about the nginx-devel
mailing list