njs_inline njs_int_t
-njs_dump_visit(njs_arr_t *list, const njs_value_t *value)
-{
- njs_object_t **p;
-
- if (njs_is_object(value)) {
- p = njs_arr_add(list);
- if (njs_slow_path(p == NULL)) {
- return NJS_ERROR;
- }
-
- *p = njs_object(value);
- }
-
- return NJS_OK;
-}
-
-
-njs_inline njs_int_t
-njs_dump_visited(njs_arr_t *list, const njs_value_t *value)
+njs_dump_visited(njs_vm_t *vm, njs_json_stringify_t *stringify,
+ const njs_value_t *value)
{
- njs_uint_t items, n;
- njs_object_t **start, *obj;
+ njs_int_t depth;
- if (!njs_is_object(value)) {
- /* External. */
- return 0;
- }
-
- start = list->start;
- items = list->items;
- obj = njs_object(value);
+ depth = stringify->depth - 1;
- for (n = 0; n < items; n++) {
- if (start[n] == obj) {
+ for (; depth >= 0; depth--) {
+ if (njs_values_same(&stringify->states[depth].value, value)) {
return 1;
}
}
njs_int_t ret;
njs_chb_t chain;
njs_str_t str;
- njs_arr_t visited;
njs_value_t *key, *val, tag;
- njs_object_t **start;
njs_json_state_t *state;
njs_string_prop_t string;
njs_object_prop_t *prop;
goto memory_error;
}
- visited.separate = 0;
- visited.pointer = 0;
-
goto done;
}
goto memory_error;
}
- start = njs_arr_init(vm->mem_pool, &visited, NULL, 8, sizeof(void *));
- if (njs_slow_path(start == NULL)) {
- goto memory_error;
- }
-
- (void) njs_dump_visit(&visited, value);
-
for ( ;; ) {
switch (state->type) {
case NJS_JSON_OBJECT:
}
if (njs_dump_is_recursive(val)) {
- if (njs_slow_path(njs_dump_visited(&visited, val))) {
+ if (njs_slow_path(njs_dump_visited(vm, stringify, val))) {
njs_chb_append_literal(&chain, "[Circular]");
break;
}
- ret = njs_dump_visit(&visited, val);
- if (njs_slow_path(ret != NJS_OK)) {
- goto memory_error;
- }
-
state = njs_json_push_stringify_state(vm, stringify, val);
if (njs_slow_path(state == NULL)) {
goto exception;
val = &njs_array_start(&state->value)[state->index++];
if (njs_dump_is_recursive(val)) {
- if (njs_slow_path(njs_dump_visited(&visited, val))) {
+ if (njs_slow_path(njs_dump_visited(vm, stringify, val))) {
njs_chb_append_literal(&chain, "[Circular]");
break;
}
- ret = njs_dump_visit(&visited, val);
- if (njs_slow_path(ret != NJS_OK)) {
- goto memory_error;
- }
-
state = njs_json_push_stringify_state(vm, stringify, val);
if (njs_slow_path(state == NULL)) {
goto exception;
done:
- njs_arr_destroy(&visited);
-
ret = njs_chb_join(&chain, &str);
if (njs_slow_path(ret != NJS_OK)) {
goto memory_error;
{ njs_str("var a = []; a[0] = a; njs.dump(a)"),
njs_str("[[Circular]]") },
+ { njs_str("var a = []; njs.dump([a,a])"),
+ njs_str("[[],[]]") },
+
+ { njs_str("var O = {}; O.x = O; njs.dump(O)"),
+ njs_str("{x:[Circular]}") },
+
+ { njs_str("var O = {}; njs.dump({x:O, y:O})"),
+ njs_str("{x:{},y:{}}") },
+
{ njs_str("var a = [], b = [a]; a[0] = b; njs.dump(a)"),
njs_str("[[[Circular]]]") },