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;
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);
}
if (closure != NULL) {
lambda->block_closures = 1;
+ lambda->closure_scope = closure->start;
size = (1 + closure->items) * sizeof(njs_value_t);
}
- lambda->nesting = node->scope->nesting;
lambda->closure_size = size;
+
+ lambda->nesting = node->scope->nesting;
lambda->arguments_object = parser->arguments_object;
lambda->local_size = parser->scope_size;
{ 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) {"