static nxt_int_t lvlhsh_unit_test_add(nxt_lvlhsh_t *lh, const nxt_lvlhsh_proto_t *proto, void *pool, uintptr_t key) { nxt_lvlhsh_query_t lhq; lhq.key_hash = key; lhq.replace = 0; lhq.key.len = sizeof(uintptr_t); lhq.key.data = (u_char *) &key; lhq.value = (void *) key; lhq.proto = proto; lhq.pool = pool; switch (nxt_lvlhsh_insert(lh, &lhq)) { case NXT_OK: return NXT_OK; case NXT_DECLINED: printf("lvlhsh unit test failed: key %08lX is already in hash\n", (long) key); default: return NXT_ERROR; } }
njs_ret_t njs_object_prototype_create(njs_vm_t *vm, njs_value_t *value) { int32_t index; nxt_int_t ret; njs_function_t *function; njs_object_prop_t *prop; nxt_lvlhsh_query_t lhq; static const njs_value_t prototype = njs_string("prototype"); function = value->data.u.function; index = function - vm->functions; if (index < 0 && index > NJS_PROTOTYPE_MAX) { vm->retval = njs_value_void; return NXT_OK; } prop = njs_object_prop_alloc(vm, &prototype); if (nxt_slow_path(prop == NULL)) { return NXT_ERROR; } prop->value.data.u.object = &vm->prototypes[index]; prop->value.type = NJS_OBJECT; prop->value.data.truth = 1; prop->enumerable = 0; prop->writable = 0; prop->configurable = 0; lhq.value = prop; lhq.key_hash = NJS_PROTOTYPE_HASH; lhq.key.len = sizeof("prototype") - 1; lhq.key.data = (u_char *) "prototype"; lhq.replace = 0; lhq.pool = vm->mem_cache_pool; lhq.proto = &njs_object_hash_proto; ret = nxt_lvlhsh_insert(&function->object.hash, &lhq); if (nxt_fast_path(ret == NXT_OK)) { vm->retval = prop->value; } /* TODO: exception NXT_ERROR. */ return ret; }
nxt_int_t njs_object_hash_create(njs_vm_t *vm, nxt_lvlhsh_t *hash, const njs_object_prop_t *prop, nxt_uint_t n) { nxt_int_t ret; nxt_lvlhsh_query_t lhq; lhq.replace = 0; lhq.proto = &njs_object_hash_proto; lhq.pool = vm->mem_cache_pool; do { lhq.key.len = prop->name.short_string.size; if (lhq.key.len != NJS_STRING_LONG) { lhq.key.data = (u_char *) prop->name.short_string.start; } else { lhq.key.len = prop->name.data.string_size; lhq.key.data = prop->name.data.u.string->start; } lhq.key_hash = nxt_djb_hash(lhq.key.data, lhq.key.len); lhq.value = (void *) prop; ret = nxt_lvlhsh_insert(hash, &lhq); if (nxt_slow_path(ret != NXT_OK)) { return NXT_ERROR; } prop++; n--; } while (n != 0); return NXT_OK; }
static njs_ret_t njs_regexp_exec_result(njs_vm_t *vm, njs_regexp_t *regexp, u_char *string, nxt_regex_match_data_t *match_data, nxt_uint_t utf8) { int *captures; u_char *start; int32_t size, length; njs_ret_t ret; nxt_uint_t i, n; njs_array_t *array; njs_object_prop_t *prop; nxt_lvlhsh_query_t lhq; static const njs_value_t njs_string_index = njs_string("index"); static const njs_value_t njs_string_input = njs_string("input"); array = njs_array_alloc(vm, regexp->pattern->ncaptures, 0); if (nxt_slow_path(array == NULL)) { goto fail; } captures = nxt_regex_captures(match_data); for (i = 0; i < regexp->pattern->ncaptures; i++) { n = 2 * i; if (captures[n] != -1) { start = &string[captures[n]]; size = captures[n + 1] - captures[n]; switch (utf8) { case 0: length = 0; break; case 1: length = size; break; default: length = nxt_utf8_length(start, size); break; } ret = njs_regexp_string_create(vm, &array->start[i], start, size, length); if (nxt_slow_path(ret != NXT_OK)) { goto fail; } } else { array->start[i] = njs_value_void; } } prop = njs_object_prop_alloc(vm, &njs_string_index); if (nxt_slow_path(prop == NULL)) { goto fail; } /* TODO: Non UTF-8 position */ njs_number_set(&prop->value, regexp->last_index + captures[0]); if (regexp->pattern->global) { regexp->last_index += captures[1]; } lhq.key_hash = NJS_INDEX_HASH; lhq.key.len = sizeof("index") - 1; lhq.key.data = (u_char *) "index"; lhq.replace = 0; lhq.value = prop; lhq.pool = vm->mem_cache_pool; lhq.proto = &njs_object_hash_proto; ret = nxt_lvlhsh_insert(&array->object.hash, &lhq); if (nxt_slow_path(ret != NXT_OK)) { goto fail; } prop = njs_object_prop_alloc(vm, &njs_string_input); if (nxt_slow_path(prop == NULL)) { goto fail; } njs_string_copy(&prop->value, ®exp->string); lhq.key_hash = NJS_INPUT_HASH; lhq.key.len = sizeof("input") - 1; lhq.key.data = (u_char *) "input"; lhq.value = prop; ret = nxt_lvlhsh_insert(&array->object.hash, &lhq); if (nxt_fast_path(ret == NXT_OK)) { vm->retval.data.u.array = array; vm->retval.type = NJS_ARRAY; vm->retval.data.truth = 1; ret = NXT_OK; goto done; } fail: ret = NXT_ERROR; done: nxt_regex_match_data_free(match_data, vm->regex_context); return ret; }
static njs_ret_t njs_object_prototype_create_constructor(njs_vm_t *vm, njs_value_t *value) { int32_t index; nxt_int_t ret; njs_value_t *constructor; njs_object_t *prototype; njs_object_prop_t *prop; nxt_lvlhsh_query_t lhq; static const njs_value_t constructor_string = njs_string("constructor"); if (njs_is_object(value)) { prototype = value->data.u.object; do { index = prototype - vm->prototypes; if (index >= 0 && index < NJS_PROTOTYPE_MAX) { goto found; } prototype = prototype->__proto__; } while (prototype != NULL); nxt_thread_log_alert("prototype not found"); return NXT_ERROR; } else { index = njs_primitive_prototype_index(value->type); prototype = &vm->prototypes[index]; } found: prop = njs_object_prop_alloc(vm, &constructor_string); if (nxt_slow_path(prop == NULL)) { return NXT_ERROR; } /* GC */ constructor = &vm->scopes[NJS_SCOPE_GLOBAL][index]; prop->value = *constructor; prop->enumerable = 0; lhq.value = prop; lhq.key_hash = NJS_CONSTRUCTOR_HASH; lhq.key.len = sizeof("constructor") - 1; lhq.key.data = (u_char *) "constructor"; lhq.replace = 0; lhq.pool = vm->mem_cache_pool; lhq.proto = &njs_object_hash_proto; ret = nxt_lvlhsh_insert(&prototype->hash, &lhq); if (nxt_fast_path(ret == NXT_OK)) { vm->retval = *constructor; } return ret; }