From: Dmitry Volyntsev Date: Tue, 11 Sep 2018 12:34:48 +0000 (+0300) Subject: Added njs_vm_object_alloc(). X-Git-Tag: 0.2.4~7 X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=df310ae19e8c4d7491a7d7ce66b83c6f9e5cc83f;p=njs.git Added njs_vm_object_alloc(). --- diff --git a/njs/njs.c b/njs/njs.c index 98728ad6..b62b8f18 100644 --- a/njs/njs.c +++ b/njs/njs.c @@ -686,6 +686,78 @@ njs_ret_t njs_vm_retval_to_ext_string(njs_vm_t *vm, nxt_str_t *retval) } +njs_ret_t +njs_vm_object_alloc(njs_vm_t *vm, njs_value_t *retval, ...) +{ + va_list args; + nxt_int_t ret; + njs_ret_t rc; + njs_value_t *name, *value; + njs_object_t *object; + njs_object_prop_t *prop; + nxt_lvlhsh_query_t lhq; + + object = njs_object_alloc(vm); + if (nxt_slow_path(object == NULL)) { + return NJS_ERROR; + } + + rc = NJS_ERROR; + + va_start(args, retval); + + for ( ;; ) { + name = va_arg(args, njs_value_t *); + if (name == NULL) { + break; + } + + value = va_arg(args, njs_value_t *); + if (value == NULL) { + njs_type_error(vm, "missed value for a key"); + goto done; + } + + if (nxt_slow_path(!njs_is_string(name))) { + njs_type_error(vm, "prop name is not a string"); + goto done; + } + + lhq.replace = 0; + lhq.pool = vm->mem_cache_pool; + lhq.proto = &njs_object_hash_proto; + + njs_string_get(name, &lhq.key); + lhq.key_hash = nxt_djb_hash(lhq.key.start, lhq.key.length); + + prop = njs_object_prop_alloc(vm, name, value, 1); + if (nxt_slow_path(prop == NULL)) { + goto done; + } + + lhq.value = prop; + + ret = nxt_lvlhsh_insert(&object->hash, &lhq); + if (nxt_slow_path(ret != NXT_OK)) { + njs_internal_error(vm, NULL); + goto done; + } + } + + rc = NJS_OK; + + retval->data.u.object = object; + retval->type = NJS_OBJECT; + retval->data.truth = 1; + +done: + + va_end(args); + + return rc; +} + + njs_value_t * njs_vm_object_prop(njs_vm_t *vm, const njs_value_t *value, const nxt_str_t *key) { diff --git a/njs/njs.h b/njs/njs.h index 149b5f59..3d81b878 100644 --- a/njs/njs.h +++ b/njs/njs.h @@ -227,6 +227,8 @@ NXT_EXPORT nxt_int_t njs_value_is_function(const njs_value_t *value); NXT_EXPORT njs_ret_t njs_vm_value_dump(njs_vm_t *vm, nxt_str_t *retval, const njs_value_t *value, nxt_uint_t indent); +NXT_EXPORT njs_ret_t njs_vm_object_alloc(njs_vm_t *vm, njs_value_t *retval, + ...); NXT_EXPORT njs_value_t *njs_vm_object_prop(njs_vm_t *vm, const njs_value_t *value, const nxt_str_t *key); diff --git a/njs/test/njs_unit_test.c b/njs/test/njs_unit_test.c index e30f2331..e504c487 100644 --- a/njs/test/njs_unit_test.c +++ b/njs/test/njs_unit_test.c @@ -10300,9 +10300,103 @@ done: } +static nxt_int_t +njs_vm_object_alloc_test(njs_vm_t * vm, nxt_bool_t disassemble, + nxt_bool_t verbose) +{ + njs_ret_t ret; + njs_value_t args[2], obj; + + static const njs_value_t num_key = njs_string("num"); + static const njs_value_t bool_key = njs_string("bool"); + + njs_value_number_set(njs_argument(&args, 0), 1); + njs_value_boolean_set(njs_argument(&args, 1), 0); + + ret = njs_vm_object_alloc(vm, &obj, NULL); + if (ret != NJS_OK) { + return NXT_ERROR; + } + + ret = njs_vm_object_alloc(vm, &obj, &num_key, NULL); + if (ret == NJS_OK) { + return NXT_ERROR; + } + + ret = njs_vm_object_alloc(vm, &obj, &num_key, &args[0], NULL); + if (ret != NJS_OK) { + return NXT_ERROR; + } + + ret = njs_vm_object_alloc(vm, &obj, &num_key, &args[0], &bool_key, &args[1], + NULL); + if (ret != NJS_OK) { + return NXT_ERROR; + } + + return NXT_OK; +} + + +typedef struct { + nxt_int_t (*test)(njs_vm_t *, nxt_bool_t, nxt_bool_t); + nxt_str_t name; +} njs_api_test_t; + + +static nxt_int_t +njs_api_test(nxt_bool_t disassemble, nxt_bool_t verbose) +{ + njs_vm_t *vm; + nxt_int_t ret, rc; + nxt_uint_t i; + njs_vm_opt_t options; + njs_api_test_t *test; + + static njs_api_test_t njs_api_test[] = + { + { njs_vm_object_alloc_test, + nxt_string("njs_vm_object_alloc_test") } + }; + + rc = NXT_ERROR; + + vm = NULL; + memset(&options, 0, sizeof(njs_vm_opt_t)); + + for (i = 0; i < nxt_nitems(njs_api_test); i++) { + test = &njs_api_test[i]; + + vm = njs_vm_create(&options); + if (vm == NULL) { + printf("njs_vm_create() failed\n"); + goto done; + } + + ret = test->test(vm, disassemble, verbose); + if (nxt_slow_path(ret != NXT_OK)) { + printf("njs_api_test: \"%.*s\" test failed\n", + (int) test->name.length, test->name.start); + goto done; + } + } + + rc = NXT_OK; + +done: + + if (vm != NULL) { + njs_vm_destroy(vm); + } + + return rc; +} + + int nxt_cdecl main(int argc, char **argv) { + nxt_int_t ret; nxt_bool_t disassemble, verbose; disassemble = 0; @@ -10324,5 +10418,10 @@ main(int argc, char **argv) } } - return njs_unit_test(disassemble, verbose); + ret = njs_unit_test(disassemble, verbose); + if (ret != NXT_OK) { + return ret; + } + + return njs_api_test(disassemble, verbose); }