[njs] Removed recursion from finding let closures.
Alexander Borisov
alexander.borisov at nginx.com
Thu Jul 15 17:34:51 UTC 2021
details: https://hg.nginx.org/njs/rev/20dec02c7283
branches:
changeset: 1681:20dec02c7283
user: Alexander Borisov <alexander.borisov at nginx.com>
date: Thu Jul 15 20:32:43 2021 +0300
description:
Removed recursion from finding let closures.
diffstat:
src/njs_generator.c | 100 +++++++++++++++++++--------------------------------
src/njs_generator.h | 2 -
2 files changed, 38 insertions(+), 64 deletions(-)
diffs (187 lines):
diff -r efdc5f18195e -r 20dec02c7283 src/njs_generator.c
--- a/src/njs_generator.c Thu Jul 15 20:32:40 2021 +0300
+++ b/src/njs_generator.c Thu Jul 15 20:32:43 2021 +0300
@@ -162,9 +162,9 @@ static njs_int_t njs_generate_for_update
static njs_int_t njs_generate_for_end(njs_vm_t *vm, njs_generator_t *generator,
njs_parser_node_t *node);
static njs_int_t njs_generate_for_let_update(njs_vm_t *vm,
- njs_generator_t *generator, njs_parser_node_t *node, size_t depth);
+ njs_generator_t *generator, njs_parser_node_t *node);
static njs_int_t njs_generate_for_resolve_closure(njs_vm_t *vm,
- njs_parser_node_t *node, size_t depth);
+ njs_parser_node_t *node);
static njs_int_t njs_generate_for_in_statement(njs_vm_t *vm,
njs_generator_t *generator, njs_parser_node_t *node);
static njs_int_t njs_generate_for_in_object(njs_vm_t *vm,
@@ -424,9 +424,6 @@ static njs_int_t njs_generate_index_rele
##__VA_ARGS__)
-#define NJS_GENERATE_MAX_DEPTH 4096
-
-
static const njs_str_t no_label = njs_str("");
static const njs_str_t return_label = njs_str("@return");
/* GCC and Clang complain about NULL argument passed to memcmp(). */
@@ -1692,7 +1689,7 @@ njs_generate_for_init(njs_vm_t *vm, njs_
* foreseen in order to generate optimized code for let updates.
*/
- ret = njs_generate_for_resolve_closure(vm, condition, generator->count);
+ ret = njs_generate_for_resolve_closure(vm, condition);
if (njs_slow_path(ret != NJS_OK)) {
return ret;
}
@@ -1736,12 +1733,12 @@ njs_generate_for_body(njs_vm_t *vm, njs_
init = node->left;
update = node->right->right->right;
- ret = njs_generate_for_resolve_closure(vm, update, generator->count);
+ ret = njs_generate_for_resolve_closure(vm, update);
if (njs_slow_path(ret != NJS_OK)) {
return ret;
}
- ret = njs_generate_for_let_update(vm, generator, init, generator->count);
+ ret = njs_generate_for_let_update(vm, generator, init);
if (njs_slow_path(ret != NJS_OK)) {
return ret;
}
@@ -1833,56 +1830,43 @@ njs_generate_for_end(njs_vm_t *vm, njs_g
static njs_int_t
njs_generate_for_let_update(njs_vm_t *vm, njs_generator_t *generator,
- njs_parser_node_t *node, size_t depth)
+ njs_parser_node_t *node)
{
njs_parser_node_t *let;
njs_vmcode_variable_t *code_var;
njs_variable_reference_t *ref;
- if (node == NULL) {
- return NJS_OK;
- }
-
- if (depth >= NJS_GENERATE_MAX_DEPTH) {
- return NJS_ERROR;
- }
-
- if (node->token_type != NJS_TOKEN_STATEMENT) {
- return NJS_OK;
- }
-
- let = node->right;
-
- if (let->token_type != NJS_TOKEN_LET
- && let->token_type != NJS_TOKEN_CONST)
- {
- return NJS_OK;
- }
-
- ref = &let->left->u.reference;
-
- if (ref->variable->closure) {
- njs_generate_code(generator, njs_vmcode_variable_t, code_var,
- NJS_VMCODE_LET_UPDATE, 0, let);
- code_var->dst = let->left->index;
- }
-
- return njs_generate_for_let_update(vm, generator, node->left, depth + 1);
+ while (node != NULL && node->token_type == NJS_TOKEN_STATEMENT) {
+ let = node->right;
+
+ if (let->token_type != NJS_TOKEN_LET
+ && let->token_type != NJS_TOKEN_CONST)
+ {
+ return NJS_OK;
+ }
+
+ ref = &let->left->u.reference;
+
+ if (ref->variable->closure) {
+ njs_generate_code(generator, njs_vmcode_variable_t, code_var,
+ NJS_VMCODE_LET_UPDATE, 0, let);
+ code_var->dst = let->left->index;
+ }
+
+ node = node->left;
+ }
+
+ return NJS_OK;
}
static njs_int_t
-njs_generate_for_resolve_closure(njs_vm_t *vm, njs_parser_node_t *node,
- size_t depth)
+njs_generate_for_resolve_closure_cb(njs_vm_t *vm, njs_parser_node_t *node,
+ void *unused)
{
- njs_int_t ret;
njs_bool_t closure;
njs_variable_t *var;
- if (node == NULL) {
- return NJS_OK;
- }
-
if (node->token_type == NJS_TOKEN_NAME) {
var = njs_variable_resolve(vm, node);
@@ -1895,26 +1879,19 @@ njs_generate_for_resolve_closure(njs_vm_
}
}
- if (depth >= NJS_GENERATE_MAX_DEPTH) {
- njs_range_error(vm, "Maximum call stack size exceeded");
- return NJS_ERROR;
- }
-
- ret = njs_generate_for_resolve_closure(vm, node->left, depth + 1);
- if (njs_slow_path(ret != NJS_OK)) {
- return ret;
- }
-
- ret = njs_generate_for_resolve_closure(vm, node->right, depth + 1);
- if (njs_slow_path(ret != NJS_OK)) {
- return ret;
- }
-
return NJS_OK;
}
static njs_int_t
+njs_generate_for_resolve_closure(njs_vm_t *vm, njs_parser_node_t *node)
+{
+ return njs_parser_traverse(vm, node, NULL,
+ njs_generate_for_resolve_closure_cb);
+}
+
+
+static njs_int_t
njs_generate_for_in_statement(njs_vm_t *vm, njs_generator_t *generator,
njs_parser_node_t *node)
{
@@ -2027,8 +2004,7 @@ njs_generate_for_in_body(njs_vm_t *vm, n
/* The loop iterator. */
if (name != NULL) {
- ret = njs_generate_for_let_update(vm, generator, foreach->left,
- generator->count);
+ ret = njs_generate_for_let_update(vm, generator, foreach->left);
if (njs_slow_path(ret != NJS_OK)) {
return ret;
}
diff -r efdc5f18195e -r 20dec02c7283 src/njs_generator.h
--- a/src/njs_generator.h Thu Jul 15 20:32:40 2021 +0300
+++ b/src/njs_generator.h Thu Jul 15 20:32:43 2021 +0300
@@ -35,8 +35,6 @@ struct njs_generator_s {
/* Parsing Function() or eval(). */
uint8_t runtime; /* 1 bit */
-
- njs_uint_t count;
};
More information about the nginx-devel
mailing list