From: Dmitry Volyntsev Date: Wed, 23 Oct 2019 11:42:38 +0000 (+0300) Subject: Refactoring iteration over external objects. X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=c38f6ccfa8f2967f96cbac506783f6f1c20faa5c;p=njs.git Refactoring iteration over external objects. Previously, two callbacks were required to support array-like iteration for external objects (foreach, next). Instead using only one callback (keys) to simplify. --- diff --git a/nginx/ngx_http_js_module.c b/nginx/ngx_http_js_module.c index d6502509..68c49b72 100644 --- a/nginx/ngx_http_js_module.c +++ b/nginx/ngx_http_js_module.c @@ -35,12 +35,6 @@ typedef struct { } ngx_http_js_ctx_t; -typedef struct { - ngx_list_part_t *part; - ngx_uint_t item; -} ngx_http_js_table_entry_t; - - typedef struct { ngx_http_request_t *request; njs_vm_event_t vm_event; @@ -62,10 +56,8 @@ static void ngx_http_js_cleanup_vm(void *data); static njs_int_t ngx_http_js_ext_get_string(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data); -static njs_int_t ngx_http_js_ext_foreach_header(njs_vm_t *vm, void *obj, - void *next, uintptr_t data); -static njs_int_t ngx_http_js_ext_next_header(njs_vm_t *vm, njs_value_t *value, - void *obj, void *next); +static njs_int_t ngx_http_js_ext_keys_header(njs_vm_t *vm, void *obj, + njs_value_t *keys, uintptr_t data); static ngx_table_elt_t *ngx_http_js_get_header(ngx_list_part_t *part, u_char *data, size_t len); static njs_int_t ngx_http_js_ext_get_header_out(njs_vm_t *vm, @@ -74,8 +66,8 @@ static njs_int_t ngx_http_js_ext_set_header_out(njs_vm_t *vm, void *obj, uintptr_t data, njs_str_t *value); static njs_int_t ngx_http_js_ext_delete_header_out(njs_vm_t *vm, void *obj, uintptr_t data, njs_bool_t delete); -static njs_int_t ngx_http_js_ext_foreach_header_out(njs_vm_t *vm, void *obj, - void *next); /*FIXME*/ +static njs_int_t ngx_http_js_ext_keys_header_out(njs_vm_t *vm, void *obj, + njs_value_t *keys); /*FIXME*/ static njs_int_t ngx_http_js_ext_get_status(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data); static njs_int_t ngx_http_js_ext_set_status(njs_vm_t *vm, void *obj, @@ -108,14 +100,12 @@ static njs_int_t ngx_http_js_ext_get_request_body(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data); static njs_int_t ngx_http_js_ext_get_header_in(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data); -static njs_int_t ngx_http_js_ext_foreach_header_in(njs_vm_t *vm, void *obj, - void *next); /*FIXME*/ +static njs_int_t ngx_http_js_ext_keys_header_in(njs_vm_t *vm, void *obj, + njs_value_t *keys); /*FIXME*/ static njs_int_t ngx_http_js_ext_get_arg(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data); -static njs_int_t ngx_http_js_ext_foreach_arg(njs_vm_t *vm, void *obj, - void *next); -static njs_int_t ngx_http_js_ext_next_arg(njs_vm_t *vm, njs_value_t *value, - void *obj, void *next); +static njs_int_t ngx_http_js_ext_keys_arg(njs_vm_t *vm, void *obj, + njs_value_t *keys); static njs_int_t ngx_http_js_ext_get_variable(njs_vm_t *vm, njs_value_t *value, void *obj, uintptr_t data); static njs_int_t ngx_http_js_ext_set_variable(njs_vm_t *vm, void *obj, @@ -229,7 +219,6 @@ static njs_external_t ngx_http_js_ext_request[] = { NULL, NULL, NULL, - NULL, offsetof(ngx_http_request_t, uri) }, { njs_str("method"), @@ -241,7 +230,6 @@ static njs_external_t ngx_http_js_ext_request[] = { NULL, NULL, NULL, - NULL, offsetof(ngx_http_request_t, method_name) }, { njs_str("httpVersion"), @@ -253,7 +241,6 @@ static njs_external_t ngx_http_js_ext_request[] = { NULL, NULL, NULL, - NULL, 0 }, { njs_str("remoteAddress"), @@ -265,7 +252,6 @@ static njs_external_t ngx_http_js_ext_request[] = { NULL, NULL, NULL, - NULL, 0 }, { njs_str("parent"), @@ -277,7 +263,6 @@ static njs_external_t ngx_http_js_ext_request[] = { NULL, NULL, NULL, - NULL, 0 }, { njs_str("requestBody"), @@ -289,7 +274,6 @@ static njs_external_t ngx_http_js_ext_request[] = { NULL, NULL, NULL, - NULL, 0 }, { njs_str("responseBody"), @@ -301,7 +285,6 @@ static njs_external_t ngx_http_js_ext_request[] = { NULL, NULL, NULL, - NULL, 0 }, { njs_str("headersIn"), @@ -311,8 +294,7 @@ static njs_external_t ngx_http_js_ext_request[] = { ngx_http_js_ext_get_header_in, NULL, NULL, - ngx_http_js_ext_foreach_header_in, - ngx_http_js_ext_next_header, + ngx_http_js_ext_keys_header_in, NULL, 0 }, @@ -323,8 +305,7 @@ static njs_external_t ngx_http_js_ext_request[] = { ngx_http_js_ext_get_arg, NULL, NULL, - ngx_http_js_ext_foreach_arg, - ngx_http_js_ext_next_arg, + ngx_http_js_ext_keys_arg, NULL, 0 }, @@ -337,7 +318,6 @@ static njs_external_t ngx_http_js_ext_request[] = { NULL, NULL, NULL, - NULL, 0 }, { njs_str("status"), @@ -349,7 +329,6 @@ static njs_external_t ngx_http_js_ext_request[] = { NULL, NULL, NULL, - NULL, offsetof(ngx_http_request_t, headers_out.status) }, { njs_str("headersOut"), @@ -359,8 +338,7 @@ static njs_external_t ngx_http_js_ext_request[] = { ngx_http_js_ext_get_header_out, ngx_http_js_ext_set_header_out, ngx_http_js_ext_delete_header_out, - ngx_http_js_ext_foreach_header_out, - ngx_http_js_ext_next_header, + ngx_http_js_ext_keys_header_out, NULL, 0 }, @@ -372,7 +350,6 @@ static njs_external_t ngx_http_js_ext_request[] = { NULL, NULL, NULL, - NULL, ngx_http_js_ext_subrequest, 0 }, @@ -384,7 +361,6 @@ static njs_external_t ngx_http_js_ext_request[] = { NULL, NULL, NULL, - NULL, ngx_http_js_ext_log, 0 }, @@ -396,7 +372,6 @@ static njs_external_t ngx_http_js_ext_request[] = { NULL, NULL, NULL, - NULL, ngx_http_js_ext_warn, 0 }, @@ -408,7 +383,6 @@ static njs_external_t ngx_http_js_ext_request[] = { NULL, NULL, NULL, - NULL, ngx_http_js_ext_error, 0 }, @@ -420,7 +394,6 @@ static njs_external_t ngx_http_js_ext_request[] = { NULL, NULL, NULL, - NULL, ngx_http_js_ext_send_header, 0 }, @@ -432,7 +405,6 @@ static njs_external_t ngx_http_js_ext_request[] = { NULL, NULL, NULL, - NULL, ngx_http_js_ext_send, 0 }, @@ -444,7 +416,6 @@ static njs_external_t ngx_http_js_ext_request[] = { NULL, NULL, NULL, - NULL, ngx_http_js_ext_finish, 0 }, @@ -456,7 +427,6 @@ static njs_external_t ngx_http_js_ext_request[] = { NULL, NULL, NULL, - NULL, ngx_http_js_ext_return, 0 }, @@ -468,7 +438,6 @@ static njs_external_t ngx_http_js_ext_request[] = { NULL, NULL, NULL, - NULL, ngx_http_js_ext_internal_redirect, 0 }, }; @@ -485,7 +454,6 @@ static njs_external_t ngx_http_js_externals[] = { NULL, NULL, NULL, - NULL, 0 }, }; @@ -822,64 +790,79 @@ ngx_http_js_ext_get_string(njs_vm_t *vm, njs_value_t *value, void *obj, static njs_int_t -ngx_http_js_ext_foreach_header(njs_vm_t *vm, void *obj, void *next, +ngx_http_js_ext_keys_header(njs_vm_t *vm, void *obj, njs_value_t *keys, uintptr_t data) { char *p = obj; - ngx_list_t *headers; - ngx_http_request_t *r; - ngx_http_js_table_entry_t *entry, **e; - - r = (ngx_http_request_t *) obj; + njs_int_t rc, cookie, x_for; + ngx_uint_t item; + ngx_list_t *headers; + njs_value_t *value; + ngx_list_part_t *part; + ngx_table_elt_t *header, *h; - entry = ngx_palloc(r->pool, sizeof(ngx_http_js_table_entry_t)); - if (entry == NULL) { + rc = njs_vm_array_alloc(vm, keys, 8); + if (rc != NJS_OK) { return NJS_ERROR; } headers = (ngx_list_t *) (p + data); + part = &headers->part; + item = 0; - entry->part = &headers->part; - entry->item = 0; + cookie = 0; + x_for = 0; - e = (ngx_http_js_table_entry_t **) next; - *e = entry; + while (part) { - return NJS_OK; -} + if (item >= part->nelts) { + part = part->next; + item = 0; + continue; + } + header = part->elts; + h = &header[item++]; -static njs_int_t -ngx_http_js_ext_next_header(njs_vm_t *vm, njs_value_t *value, void *obj, - void *next) -{ - ngx_http_js_table_entry_t **e = next; + if (h->hash == 0) { + continue; + } - ngx_table_elt_t *header, *h; - ngx_http_js_table_entry_t *entry; + if (h->key.len == njs_length("Cookie") + && ngx_strncasecmp(h->key.data, (u_char *) "Cookie", + h->key.len) == 0) + { + if (cookie) { + continue; + } - entry = *e; + cookie = 1; + } - while (entry->part) { + if (h->key.len == njs_length("X-Forwarded-For") + && ngx_strncasecmp(h->key.data, (u_char *) "X-Forwarded-For", + h->key.len) == 0) + { + if (x_for) { + continue; + } - if (entry->item >= entry->part->nelts) { - entry->part = entry->part->next; - entry->item = 0; - continue; + x_for = 1; } - header = entry->part->elts; - h = &header[entry->item++]; - - if (h->hash == 0) { - continue; + value = njs_vm_array_push(vm, keys); + if (value == NULL) { + return NJS_ERROR; } - return njs_vm_value_string_set(vm, value, h->key.data, h->key.len); + rc = njs_vm_value_string_set(vm, value, h->key.data, h->key.len); + if (rc != NJS_OK) { + return NJS_ERROR; + } } - return NJS_DONE; + return NJS_OK; } @@ -1078,9 +1061,9 @@ ngx_http_js_ext_delete_header_out(njs_vm_t *vm, void *obj, uintptr_t data, static njs_int_t -ngx_http_js_ext_foreach_header_out(njs_vm_t *vm, void *obj, void *next) +ngx_http_js_ext_keys_header_out(njs_vm_t *vm, void *obj, njs_value_t *keys) { - return ngx_http_js_ext_foreach_header(vm, obj, next, + return ngx_http_js_ext_keys_header(vm, obj, keys, offsetof(ngx_http_request_t, headers_out.headers)); } @@ -1604,9 +1587,9 @@ multi: static njs_int_t -ngx_http_js_ext_foreach_header_in(njs_vm_t *vm, void *obj, void *next) +ngx_http_js_ext_keys_header_in(njs_vm_t *vm, void *obj, njs_value_t *keys) { - return ngx_http_js_ext_foreach_header(vm, obj, next, + return ngx_http_js_ext_keys_header(vm, obj, keys, offsetof(ngx_http_request_t, headers_in.headers)); } @@ -1632,67 +1615,50 @@ ngx_http_js_ext_get_arg(njs_vm_t *vm, njs_value_t *value, void *obj, static njs_int_t -ngx_http_js_ext_foreach_arg(njs_vm_t *vm, void *obj, void *next) +ngx_http_js_ext_keys_arg(njs_vm_t *vm, void *obj, njs_value_t *keys) { - ngx_str_t *entry, **e; + u_char *v, *p, *start, *end; + njs_int_t rc; + njs_value_t *value; ngx_http_request_t *r; r = (ngx_http_request_t *) obj; - entry = ngx_palloc(r->pool, sizeof(ngx_str_t)); - if (entry == NULL) { + rc = njs_vm_array_alloc(vm, keys, 8); + if (rc != NJS_OK) { return NJS_ERROR; } - *entry = r->args; - - e = (ngx_str_t **) next; - *e = entry; - - return NJS_OK; -} - - -static njs_int_t -ngx_http_js_ext_next_arg(njs_vm_t *vm, njs_value_t *value, void *obj, - void *next) -{ - ngx_str_t **e = next; - - size_t len; - u_char *v, *p, *start, *end; - ngx_str_t *entry; - - entry = *e; - - if (entry->len == 0) { - return NJS_DONE; - } - - start = entry->data; - end = start + entry->len; + start = r->args.data; + end = start + r->args.len; - p = ngx_strlchr(start, end, '&'); - if (p == NULL) { - p = end; - } + while (start < end) { + p = ngx_strlchr(start, end, '&'); + if (p == NULL) { + p = end; + } - v = ngx_strlchr(start, p, '='); - if (v == NULL) { - v = p; - } + v = ngx_strlchr(start, p, '='); + if (v == NULL) { + v = p; + } - len = v - start; + if (v != start) { + value = njs_vm_array_push(vm, keys); + if (value == NULL) { + return NJS_ERROR; + } - if (p != end) { - entry->data = &p[1]; - entry->len = end - entry->data; + rc = njs_vm_value_string_set(vm, value, start, v - start); + if (rc != NJS_OK) { + return NJS_ERROR; + } + } - } else { - entry->len = 0; + start = p + 1; } - return njs_vm_value_string_set(vm, value, start, len); + return NJS_OK; } diff --git a/nginx/ngx_stream_js_module.c b/nginx/ngx_stream_js_module.c index d6f07e5b..00610dfa 100644 --- a/nginx/ngx_stream_js_module.c +++ b/nginx/ngx_stream_js_module.c @@ -211,7 +211,6 @@ static njs_external_t ngx_stream_js_ext_session[] = { NULL, NULL, NULL, - NULL, 0 }, { njs_str("variables"), @@ -223,7 +222,6 @@ static njs_external_t ngx_stream_js_ext_session[] = { NULL, NULL, NULL, - NULL, 0 }, { njs_str("allow"), @@ -234,7 +232,6 @@ static njs_external_t ngx_stream_js_ext_session[] = { NULL, NULL, NULL, - NULL, ngx_stream_js_ext_done, 0 }, @@ -246,7 +243,6 @@ static njs_external_t ngx_stream_js_ext_session[] = { NULL, NULL, NULL, - NULL, ngx_stream_js_ext_deny, 0 }, @@ -258,7 +254,6 @@ static njs_external_t ngx_stream_js_ext_session[] = { NULL, NULL, NULL, - NULL, ngx_stream_js_ext_decline, 0 }, @@ -270,7 +265,6 @@ static njs_external_t ngx_stream_js_ext_session[] = { NULL, NULL, NULL, - NULL, ngx_stream_js_ext_done, 0 }, @@ -282,7 +276,6 @@ static njs_external_t ngx_stream_js_ext_session[] = { NULL, NULL, NULL, - NULL, ngx_stream_js_ext_log, 0 }, @@ -294,7 +287,6 @@ static njs_external_t ngx_stream_js_ext_session[] = { NULL, NULL, NULL, - NULL, ngx_stream_js_ext_warn, 0 }, @@ -306,7 +298,6 @@ static njs_external_t ngx_stream_js_ext_session[] = { NULL, NULL, NULL, - NULL, ngx_stream_js_ext_error, 0 }, @@ -318,7 +309,6 @@ static njs_external_t ngx_stream_js_ext_session[] = { NULL, NULL, NULL, - NULL, ngx_stream_js_ext_on, 0 }, @@ -330,7 +320,6 @@ static njs_external_t ngx_stream_js_ext_session[] = { NULL, NULL, NULL, - NULL, ngx_stream_js_ext_off, 0 }, @@ -342,7 +331,6 @@ static njs_external_t ngx_stream_js_ext_session[] = { NULL, NULL, NULL, - NULL, ngx_stream_js_ext_send, 0 }, @@ -360,7 +348,6 @@ static njs_external_t ngx_stream_js_externals[] = { NULL, NULL, NULL, - NULL, 0 }, }; diff --git a/src/njs.h b/src/njs.h index 2d37fee3..90be1e57 100644 --- a/src/njs.h +++ b/src/njs.h @@ -66,9 +66,8 @@ typedef njs_int_t (*njs_extern_set_t)(njs_vm_t *vm, void *obj, uintptr_t data, njs_str_t *value); typedef njs_int_t (*njs_extern_find_t)(njs_vm_t *vm, void *obj, uintptr_t data, njs_bool_t delete); -typedef njs_int_t (*njs_extern_foreach_t)(njs_vm_t *vm, void *obj, void *next); -typedef njs_int_t (*njs_extern_next_t)(njs_vm_t *vm, njs_value_t *value, - void *obj, void *next); +typedef njs_int_t (*njs_extern_keys_t)(njs_vm_t *vm, void *obj, + njs_value_t *keys); typedef njs_int_t (*njs_extern_method_t)(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused); @@ -92,8 +91,7 @@ struct njs_external_s { njs_extern_set_t set; njs_extern_find_t find; - njs_extern_foreach_t foreach; - njs_extern_next_t next; + njs_extern_keys_t keys; njs_extern_method_t method; diff --git a/src/njs_extern.c b/src/njs_extern.c index 73b952bb..a7d8d0b6 100644 --- a/src/njs_extern.c +++ b/src/njs_extern.c @@ -89,8 +89,7 @@ njs_vm_external_add(njs_vm_t *vm, njs_lvlhsh_t *hash, njs_external_t *external, ext->get = external->get; ext->set = external->set; ext->find = external->find; - ext->foreach = external->foreach; - ext->next = external->next; + ext->keys = external->keys; ext->data = external->data; if (external->method != NULL) { diff --git a/src/njs_extern.h b/src/njs_extern.h index c11557b3..6a3d9ab5 100644 --- a/src/njs_extern.h +++ b/src/njs_extern.h @@ -26,8 +26,7 @@ struct njs_extern_s { njs_extern_set_t set; njs_extern_find_t find; - njs_extern_foreach_t foreach; - njs_extern_next_t next; + njs_extern_keys_t keys; njs_function_t *function; diff --git a/src/njs_json.c b/src/njs_json.c index 45e24db4..9dff7148 100644 --- a/src/njs_json.c +++ b/src/njs_json.c @@ -2295,12 +2295,8 @@ njs_dump_value(njs_json_stringify_t *stringify, const njs_value_t *value, njs_dump_item("\"find\""); } - if (ext_proto->foreach != NULL) { - njs_dump_item("\"foreach\""); - } - - if (ext_proto->next != NULL) { - njs_dump_item("\"next\""); + if (ext_proto->keys != NULL) { + njs_dump_item("\"keys\""); } return njs_json_buf_append(stringify, "]}", 2); diff --git a/src/njs_shell.c b/src/njs_shell.c index 68277dfe..07f7108f 100644 --- a/src/njs_shell.c +++ b/src/njs_shell.c @@ -112,7 +112,6 @@ static njs_external_t njs_ext_console[] = { NULL, NULL, NULL, - NULL, njs_ext_console_log, 0 }, @@ -124,7 +123,6 @@ static njs_external_t njs_ext_console[] = { NULL, NULL, NULL, - NULL, njs_ext_console_dump, 0 }, @@ -136,7 +134,6 @@ static njs_external_t njs_ext_console[] = { NULL, NULL, NULL, - NULL, njs_ext_console_help, 0 }, @@ -148,7 +145,6 @@ static njs_external_t njs_ext_console[] = { NULL, NULL, NULL, - NULL, njs_ext_console_time, 0 }, @@ -160,7 +156,6 @@ static njs_external_t njs_ext_console[] = { NULL, NULL, NULL, - NULL, njs_ext_console_time_end, 0 }, }; @@ -176,7 +171,6 @@ static njs_external_t njs_externals[] = { NULL, NULL, NULL, - NULL, 0 }, }; diff --git a/src/njs_value.c b/src/njs_value.c index 7f23f159..4d0cf7e8 100644 --- a/src/njs_value.c +++ b/src/njs_value.c @@ -191,13 +191,34 @@ njs_array_t * njs_value_enumerate(njs_vm_t *vm, const njs_value_t *value, njs_object_enum_t kind, njs_bool_t all) { + void *obj; + njs_int_t ret; + njs_value_t keys; njs_object_value_t obj_val; + const njs_extern_t *ext_proto; if (njs_is_object(value)) { return njs_object_enumerate(vm, njs_object(value), kind, all); } if (value->type != NJS_STRING) { + if (kind == NJS_ENUM_KEYS && njs_is_external(value)) { + ext_proto = value->external.proto; + + if (ext_proto->keys != NULL) { + obj = njs_extern_object(vm, value); + + ret = ext_proto->keys(vm, obj, &keys); + if (njs_slow_path(ret != NJS_OK)) { + return NULL; + } + + return njs_array(&keys); + } + + return njs_extern_keys_array(vm, ext_proto); + } + return njs_array_alloc(vm, 0, NJS_ARRAY_SPARE); } @@ -212,13 +233,34 @@ njs_array_t * njs_value_own_enumerate(njs_vm_t *vm, const njs_value_t *value, njs_object_enum_t kind, njs_bool_t all) { + void *obj; + njs_int_t ret; + njs_value_t keys; njs_object_value_t obj_val; + const njs_extern_t *ext_proto; if (njs_is_object(value)) { return njs_object_own_enumerate(vm, njs_object(value), kind, all); } if (value->type != NJS_STRING) { + if (kind == NJS_ENUM_KEYS && njs_is_external(value)) { + ext_proto = value->external.proto; + + if (ext_proto->keys != NULL) { + obj = njs_extern_object(vm, value); + + ret = ext_proto->keys(vm, obj, &keys); + if (njs_slow_path(ret != NJS_OK)) { + return NULL; + } + + return njs_array(&keys); + } + + return njs_extern_keys_array(vm, ext_proto); + } + return njs_array_alloc(vm, 0, NJS_ARRAY_SPARE); } diff --git a/src/njs_vmcode.c b/src/njs_vmcode.c index 77993ed3..68d5a372 100644 --- a/src/njs_vmcode.c +++ b/src/njs_vmcode.c @@ -31,8 +31,6 @@ static njs_jump_off_t njs_vmcode_property_in(njs_vm_t *vm, njs_value_t *value, njs_value_t *key); static njs_jump_off_t njs_vmcode_property_foreach(njs_vm_t *vm, njs_value_t *object, njs_value_t *invld, u_char *pc); -static njs_jump_off_t njs_vmcode_property_next(njs_vm_t *vm, - njs_value_t *object, njs_value_t *value, u_char *pc); static njs_jump_off_t njs_vmcode_instance_of(njs_vm_t *vm, njs_value_t *object, njs_value_t *constructor); static njs_jump_off_t njs_vmcode_typeof(njs_vm_t *vm, njs_value_t *value, @@ -771,25 +769,21 @@ next: break; case NJS_VMCODE_PROPERTY_NEXT: - if (!njs_is_external(value1)) { - pnext = (njs_vmcode_prop_next_t *) pc; - retval = njs_vmcode_operand(vm, pnext->retval); + pnext = (njs_vmcode_prop_next_t *) pc; + retval = njs_vmcode_operand(vm, pnext->retval); - next = value2->data.u.next; + next = value2->data.u.next; - if (next->index < next->array->length) { - *retval = next->array->data[next->index++]; + if (next->index < next->array->length) { + *retval = next->array->data[next->index++]; - ret = pnext->offset; - break; - } + ret = pnext->offset; + break; } - ret = njs_vmcode_property_next(vm, value1, value2, pc); - if (njs_slow_path(ret == NJS_ERROR)) { - goto error; - } + njs_mp_free(vm->mem_pool, next); + ret = sizeof(njs_vmcode_prop_next_t); break; case NJS_VMCODE_THIS: @@ -1306,27 +1300,9 @@ static njs_jump_off_t njs_vmcode_property_foreach(njs_vm_t *vm, njs_value_t *object, njs_value_t *invld, u_char *pc) { - void *obj; - njs_jump_off_t ret; - const njs_extern_t *ext_proto; njs_property_next_t *next; njs_vmcode_prop_foreach_t *code; - if (njs_is_external(object)) { - ext_proto = object->external.proto; - - if (ext_proto->foreach != NULL) { - obj = njs_extern_object(vm, object); - - ret = ext_proto->foreach(vm, obj, &vm->retval); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - } - - goto done; - } - next = njs_mp_alloc(vm->mem_pool, sizeof(njs_property_next_t)); if (njs_slow_path(next == NULL)) { njs_memory_error(vm); @@ -1342,64 +1318,12 @@ njs_vmcode_property_foreach(njs_vm_t *vm, njs_value_t *object, vm->retval.data.u.next = next; -done: - code = (njs_vmcode_prop_foreach_t *) pc; return code->offset; } -static njs_jump_off_t -njs_vmcode_property_next(njs_vm_t *vm, njs_value_t *object, njs_value_t *value, - u_char *pc) -{ - void *obj; - njs_value_t *retval; - njs_jump_off_t ret; - njs_property_next_t *next; - const njs_extern_t *ext_proto; - njs_vmcode_prop_next_t *code; - - code = (njs_vmcode_prop_next_t *) pc; - retval = njs_vmcode_operand(vm, code->retval); - - if (njs_is_external(object)) { - ext_proto = object->external.proto; - - if (ext_proto->next != NULL) { - obj = njs_extern_object(vm, object); - - ret = ext_proto->next(vm, retval, obj, value); - - if (ret == NJS_OK) { - return code->offset; - } - - if (njs_slow_path(ret == NJS_ERROR)) { - return ret; - } - - /* ret == NJS_DONE. */ - } - - return sizeof(njs_vmcode_prop_next_t); - } - - next = value->data.u.next; - - if (next->index < next->array->length) { - *retval = next->array->data[next->index++]; - - return code->offset; - } - - njs_mp_free(vm->mem_pool, next); - - return sizeof(njs_vmcode_prop_next_t); -} - - static njs_jump_off_t njs_vmcode_instance_of(njs_vm_t *vm, njs_value_t *object, njs_value_t *constructor) diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index c929b3e2..fecd3d4c 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -14029,7 +14029,7 @@ static njs_unit_test_t njs_test[] = njs_str("{a:{type:\"property\",props:[\"getter\"]},b:{type:\"property\",props:[\"getter\"]}}") }, { njs_str("njs.dump($r.header)"), - njs_str("{type:\"object\",props:[\"getter\",\"foreach\",\"next\"]}") }, + njs_str("{type:\"object\",props:[\"getter\",\"keys\"]}") }, { njs_str("njs.dump(njs) == `{version:'${njs.version}'}`"), njs_str("true") }, @@ -14988,32 +14988,32 @@ njs_unit_test_header_external(njs_vm_t *vm, njs_value_t *value, void *obj, static njs_int_t -njs_unit_test_header_foreach_external(njs_vm_t *vm, void *obj, void *next) +njs_unit_test_header_keys_external(njs_vm_t *vm, void *obj, njs_value_t *keys) { - u_char *s; + njs_int_t rc, i; + njs_value_t *value; + u_char k[2]; - s = next; - s[0] = '0'; - s[1] = '0'; - - return NJS_OK; -} + rc = njs_vm_array_alloc(vm, keys, 4); + if (rc != NJS_OK) { + return NJS_ERROR; + } + k[0] = '0'; + k[1] = '1'; -static njs_int_t -njs_unit_test_header_next_external(njs_vm_t *vm, njs_value_t *value, void *obj, - void *next) -{ - u_char *s; + for (i = 0; i < 3; i++) { + value = njs_vm_array_push(vm, keys); + if (value == NULL) { + return NJS_ERROR; + } - s = next; - s[1]++; + (void) njs_vm_value_string_set(vm, value, k, 2); - if (s[1] == '4') { - return NJS_DONE; + k[1]++; } - return njs_vm_value_string_set(vm, value, s, 2); + return NJS_OK; } @@ -15102,7 +15102,6 @@ static njs_external_t njs_unit_test_r_props[] = { NULL, NULL, NULL, - NULL, 0 }, { njs_str("b"), @@ -15114,7 +15113,6 @@ static njs_external_t njs_unit_test_r_props[] = { NULL, NULL, NULL, - NULL, 42 }, }; @@ -15130,7 +15128,6 @@ static njs_external_t njs_unit_test_r_external[] = { NULL, NULL, NULL, - NULL, offsetof(njs_unit_test_req_t, uri) }, { njs_str("host"), @@ -15142,7 +15139,6 @@ static njs_external_t njs_unit_test_r_external[] = { NULL, NULL, NULL, - NULL, 0 }, { njs_str("props"), @@ -15154,7 +15150,6 @@ static njs_external_t njs_unit_test_r_external[] = { NULL, NULL, NULL, - NULL, 0 }, { njs_str("vars"), @@ -15166,7 +15161,6 @@ static njs_external_t njs_unit_test_r_external[] = { njs_unit_test_r_del_vars, NULL, NULL, - NULL, 0 }, { njs_str("consts"), @@ -15178,7 +15172,6 @@ static njs_external_t njs_unit_test_r_external[] = { NULL, NULL, NULL, - NULL, 0 }, { njs_str("header"), @@ -15188,8 +15181,7 @@ static njs_external_t njs_unit_test_r_external[] = { njs_unit_test_header_external, NULL, NULL, - njs_unit_test_header_foreach_external, - njs_unit_test_header_next_external, + njs_unit_test_header_keys_external, NULL, 0 }, @@ -15201,7 +15193,6 @@ static njs_external_t njs_unit_test_r_external[] = { NULL, NULL, NULL, - NULL, njs_unit_test_method_external, 0 }, @@ -15213,7 +15204,6 @@ static njs_external_t njs_unit_test_r_external[] = { NULL, NULL, NULL, - NULL, njs_unit_test_create_external, 0 }, @@ -15231,7 +15221,6 @@ static njs_external_t njs_test_external[] = { NULL, NULL, NULL, - NULL, 0 }, };