}
+static njs_bool_t
+njs_generate_is_declaration(njs_parser_node_t *node)
+{
+ return node->token_type == NJS_TOKEN_VAR
+ || node->token_type == NJS_TOKEN_LET
+ || node->token_type == NJS_TOKEN_CONST;
+}
+
+
njs_inline njs_bool_t
njs_generate_is_property_call_source(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)
+njs_generate_let_update(njs_vm_t *vm, njs_generator_t *generator,
+ njs_parser_node_t *let)
{
- njs_parser_node_t *let;
njs_vmcode_variable_t *code_var;
njs_variable_reference_t *ref;
- 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_DECLINED;
+ }
- 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, let);
+ code_var->dst = let->left->index;
+ }
+
+ 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, let);
- code_var->dst = let->left->index;
+static njs_int_t
+njs_generate_for_let_update(njs_vm_t *vm, njs_generator_t *generator,
+ njs_parser_node_t *node)
+{
+ njs_int_t ret;
+
+ while (node != NULL && node->token_type == NJS_TOKEN_STATEMENT) {
+ ret = njs_generate_let_update(vm, generator, node->right);
+ if (ret != NJS_OK) {
+ return (ret == NJS_DECLINED) ? NJS_OK : ret;
}
node = node->left;
njs_parser_node_t *node)
{
njs_int_t ret;
- njs_parser_node_t *foreach, *name;
+ njs_parser_node_t *foreach;
njs_generator_loop_ctx_t *ctx;
njs_vmcode_prop_foreach_t *prop_foreach;
ctx = generator->context;
foreach = node->left;
- name = foreach->left->right;
-
- if (name != NULL) {
- ctx->var->init = 1;
- }
njs_generate_code(generator, njs_vmcode_prop_foreach_t, prop_foreach,
NJS_VMCODE_PROPERTY_FOREACH, foreach);
foreach = node->left;
- if (!njs_generate_is_property_lvalue(foreach->left)) {
- name = foreach->left->right;
+ if (njs_generate_is_declaration(foreach->left)) {
+ name = foreach->left->left;
- if (name != NULL) {
- name = name->left;
-
- ret = njs_generate_variable_wo_dest(vm, generator, name,
+ ret = njs_generate_variable_wo_dest(vm, generator, name,
NJS_DECLARATION, &ctx.var);
- if (njs_slow_path(ret != NJS_OK)) {
- return NJS_ERROR;
- }
+ if (njs_slow_path(ret != NJS_OK)) {
+ return NJS_ERROR;
+ }
- ctx.index_next_value = name->index;
+ ctx.index_next_value = name->index;
- njs_generator_next(generator, njs_generate, foreach->right);
+ njs_generator_next(generator, njs_generate, foreach->right);
- return njs_generator_after(vm, generator,
- njs_queue_first(&generator->stack), node,
- njs_generate_for_in_object,
- &ctx, sizeof(njs_generator_loop_ctx_t));
- }
+ return njs_generator_after(vm, generator,
+ njs_queue_first(&generator->stack), node,
+ njs_generate_for_in_object,
+ &ctx, sizeof(njs_generator_loop_ctx_t));
- } else {
+ } else if (njs_generate_is_property_lvalue(foreach->left)) {
/* foreach->right is object in 'in object'. */
njs_generate_for_in_object_left_hand_expr,
&ctx, sizeof(njs_generator_loop_ctx_t));
+ } else if (foreach->left->token_type == NJS_TOKEN_NAME) {
+
+ njs_generator_next(generator, njs_generate, foreach->right);
+
+ return njs_generator_after(vm, generator,
+ njs_queue_first(&generator->stack), node,
+ njs_generate_for_in_object_wo_decl,
+ &ctx, sizeof(njs_generator_loop_ctx_t));
}
- njs_generator_next(generator, njs_generate, foreach->right);
+ njs_internal_error(vm, "unexpected for-in target");
- return njs_generator_after(vm, generator,
- njs_queue_first(&generator->stack), node,
- njs_generate_for_in_object_wo_decl,
- &ctx, sizeof(njs_generator_loop_ctx_t));
+ return NJS_ERROR;
}
njs_generate_for_in_object(njs_vm_t *vm, njs_generator_t *generator,
njs_parser_node_t *node)
{
- njs_parser_node_t *foreach, *name;
+ njs_parser_node_t *foreach;
njs_generator_loop_ctx_t *ctx;
njs_vmcode_prop_foreach_t *prop_foreach;
ctx = generator->context;
foreach = node->left;
- name = foreach->left->right;
-
- if (name != NULL) {
- ctx->var->init = 1;
- }
+ ctx->var->init = 1;
njs_generate_code(generator, njs_vmcode_prop_foreach_t, prop_foreach,
NJS_VMCODE_PROPERTY_FOREACH, foreach);
{
njs_int_t ret;
njs_jump_off_t prop_offset;
- njs_parser_node_t *foreach, *name;
+ njs_parser_node_t *foreach;
njs_vmcode_prop_next_t *prop_next;
njs_generator_loop_ctx_t *ctx;
ctx = generator->context;
foreach = node->left;
- name = foreach->left->right;
/* The loop iterator. */
- if (name != NULL) {
- ret = njs_generate_for_let_update(vm, generator, foreach->left);
- if (njs_slow_path(ret != NJS_OK)) {
+ if (njs_generate_is_declaration(foreach->left)) {
+ ret = njs_generate_let_update(vm, generator, foreach->left);
+ if (njs_slow_path(ret != NJS_OK && ret != NJS_DECLINED)) {
return ret;
}
}