njs_parser_node_t *node)
{
nxt_array_t *cache;
- njs_value_t *value;
- njs_index_t index, *last;
+ njs_index_t *last;
njs_parser_scope_t *scope;
cache = generator->index_cache;
scope = scope->parent;
}
- if (vm->options.accumulative && scope->type == NJS_SCOPE_GLOBAL) {
- /*
- * When non-clonable VM runs in accumulative mode
- * all global variables are allocated in absolute scope
- * to simplify global scope handling.
- */
- value = nxt_mp_align(vm->mem_pool, sizeof(njs_value_t),
- sizeof(njs_value_t));
- if (nxt_slow_path(value == NULL)) {
- return NJS_INDEX_ERROR;
- }
-
- index = (njs_index_t) value;
-
- } else {
- value = nxt_array_add(scope->values[0], &njs_array_mem_proto,
- vm->mem_pool);
- if (nxt_slow_path(value == NULL)) {
- return NJS_INDEX_ERROR;
- }
-
- index = scope->next_index[0];
- scope->next_index[0] += sizeof(njs_value_t);
- }
-
- *value = njs_value_invalid;
-
- return index;
+ return njs_scope_next_index(vm, scope, NJS_SCOPE_INDEX_LOCAL,
+ &njs_value_invalid);
}
{
nxt_int_t ret;
nxt_uint_t scope_index;
- nxt_array_t *values;
njs_index_t index;
- njs_value_t *value;
njs_variable_t *var;
+ const njs_value_t *default_value;
njs_variable_reference_t *vr;
vr = &node->u.reference;
goto not_found;
}
- if (vm->options.accumulative && vr->scope->type == NJS_SCOPE_GLOBAL) {
- /*
- * When non-clonable VM runs in accumulative mode all
- * global variables should be allocated in absolute scope
- * to share them among consecutive VM invocations.
- */
- value = nxt_mp_align(vm->mem_pool, sizeof(njs_value_t),
- sizeof(njs_value_t));
- if (nxt_slow_path(value == NULL)) {
- njs_memory_error(vm);
- return NULL;
- }
-
- index = (njs_index_t) value;
+ default_value = njs_is_object(&var->value) ? &var->value : &njs_value_void;
- } else {
- values = vr->scope->values[scope_index];
+ index = njs_scope_next_index(vm, vr->scope, scope_index, default_value);
- if (values == NULL) {
- values = nxt_array_create(4, sizeof(njs_value_t),
- &njs_array_mem_proto, vm->mem_pool);
- if (nxt_slow_path(values == NULL)) {
- return NULL;
- }
-
- vr->scope->values[scope_index] = values;
- }
-
- value = nxt_array_add(values, &njs_array_mem_proto, vm->mem_pool);
- if (nxt_slow_path(value == NULL)) {
- return NULL;
- }
-
- index = vr->scope->next_index[scope_index];
- vr->scope->next_index[scope_index] += sizeof(njs_value_t);
- }
-
- if (njs_is_object(&var->value)) {
- *value = var->value;
-
- } else {
- *value = njs_value_void;
+ if (nxt_slow_path(index == NJS_INDEX_ERROR)) {
+ return NULL;
}
var->index = index;
}
+njs_index_t
+njs_scope_next_index(njs_vm_t *vm, njs_parser_scope_t *scope,
+ nxt_uint_t scope_index, const njs_value_t *default_value)
+{
+ njs_index_t index;
+ njs_value_t *value;
+ nxt_array_t *values;
+
+ if (vm->options.accumulative && scope->type == NJS_SCOPE_GLOBAL) {
+ /*
+ * When non-clonable VM runs in accumulative mode all
+ * global variables should be allocated in absolute scope
+ * to share them among consecutive VM invocations.
+ */
+ value = nxt_mp_align(vm->mem_pool, sizeof(njs_value_t),
+ sizeof(njs_value_t));
+ if (nxt_slow_path(value == NULL)) {
+ return NJS_INDEX_ERROR;
+ }
+
+ index = (njs_index_t) value;
+
+ } else {
+ values = scope->values[scope_index];
+
+ if (values == NULL) {
+ values = nxt_array_create(4, sizeof(njs_value_t),
+ &njs_array_mem_proto, vm->mem_pool);
+ if (nxt_slow_path(values == NULL)) {
+ return NJS_INDEX_ERROR;
+ }
+
+ scope->values[scope_index] = values;
+ }
+
+ value = nxt_array_add(values, &njs_array_mem_proto, vm->mem_pool);
+ if (nxt_slow_path(value == NULL)) {
+ return NJS_INDEX_ERROR;
+ }
+
+ index = scope->next_index[scope_index];
+ scope->next_index[scope_index] += sizeof(njs_value_t);
+ }
+
+ *value = *default_value;
+
+ return index;
+}
+
+
static njs_variable_t *
njs_variable_alloc(njs_vm_t *vm, nxt_str_t *name, njs_variable_type_t type)
{