Skip to content

Commit b480f00

Browse files
Introduce njs_atom_atomize_key().
1 parent e6b3f04 commit b480f00

File tree

4 files changed

+89
-1
lines changed

4 files changed

+89
-1
lines changed

src/njs_atom.c

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,87 @@ njs_atom_hash_init()
137137
return;
138138
};
139139

140+
141+
/*
142+
* value is always key: string or number or symbol.
143+
*
144+
* symbol always contians atom_id by construction. do nothing;
145+
* number if short number it is atomized by "| 0x80000000";
146+
* string if represents short number it is atomized by "| 0x80000000";
147+
*
148+
* for string and symbol atom_ids common range is uint32_t < 0x80000000.
149+
*/
150+
151+
njs_int_t
152+
njs_atom_atomize_key(njs_vm_t *vm, njs_value_t *value)
153+
{
154+
double num;
155+
uint32_t hash_id;
156+
njs_int_t ret;
157+
njs_value_t val_str;
158+
const njs_value_t *entry;
159+
160+
switch (value->type) {
161+
case NJS_STRING:
162+
num = njs_key_to_index(value);
163+
if (njs_fast_path(njs_key_is_integer_index(num, value)) &&
164+
((uint32_t) num) < 0x80000000)
165+
{
166+
value->atom_id = ((uint32_t) num) | 0x80000000;
167+
168+
} else {
169+
hash_id = njs_djb_hash(value->string.data->start,
170+
value->string.data->size);
171+
172+
entry = njs_lexer_keyword_find(vm, value->string.data->start,
173+
value->string.data->size,
174+
value->string.data->length,
175+
hash_id);
176+
if (njs_slow_path(entry == NULL)) {
177+
return NJS_ERROR;
178+
}
179+
180+
/* TODO: if (<<value is string>>) <<try release>>(string) */
181+
*value = *entry;
182+
}
183+
break;
184+
185+
case NJS_NUMBER:
186+
num = value->data.u.number;
187+
if (njs_fast_path(njs_key_is_integer_index(num, value)) &&
188+
((uint32_t) num) < 0x80000000)
189+
{
190+
value->atom_id = ((uint32_t) num) | 0x80000000;
191+
192+
} else {
193+
/* convert num to string, and atomize it. */
194+
ret = njs_number_to_string(vm, &val_str, value);
195+
if (ret != NJS_OK) {
196+
return ret;
197+
}
198+
199+
if (val_str.atom_id == 0) {
200+
hash_id = njs_djb_hash(val_str.string.data->start,
201+
val_str.string.data->size);
202+
203+
entry = njs_lexer_keyword_find(vm, val_str.string.data->start,
204+
val_str.string.data->size,
205+
val_str.string.data->length,
206+
hash_id);
207+
if (njs_slow_path(entry == NULL)) {
208+
return NJS_ERROR;
209+
}
210+
211+
value->atom_id = entry->atom_id;
212+
213+
} else {
214+
value->atom_id = val_str.atom_id;
215+
}
216+
}
217+
break;
218+
default:
219+
/* NJS_SYMBOL: do nothing. */
220+
}
221+
222+
return NJS_OK;
223+
}

src/njs_atom.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,12 @@ typedef struct {
3131

3232

3333
void njs_atom_hash_init(void);
34+
njs_int_t njs_atom_atomize_key(njs_vm_t *vm, njs_value_t *value);
3435

3536

3637
extern njs_atom_values_t njs_atom;
3738
extern njs_flathsh_t njs_atom_hash;
3839
extern uint32_t njs_atom_hash_atom_id;
3940

41+
4042
#endif /* _NJS_ATOM_H_INCLUDED_ */

src/njs_lexer.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -727,7 +727,7 @@ njs_lexer_hash_test(njs_lvlhsh_query_t *lhq, void *data)
727727
}
728728

729729

730-
static njs_value_t *
730+
njs_value_t *
731731
njs_lexer_keyword_find(njs_vm_t *vm, u_char *key, size_t size, size_t length,
732732
uint32_t hash)
733733
{

src/njs_lexer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,8 @@ njs_int_t njs_lexer_in_stack_push(njs_lexer_t *lexer);
288288
void njs_lexer_in_stack_pop(njs_lexer_t *lexer);
289289
void njs_lexer_in_fail_set(njs_lexer_t *lexer, njs_int_t flag);
290290
njs_int_t njs_lexer_in_fail_get(njs_lexer_t *lexer);
291+
njs_value_t *njs_lexer_keyword_find(njs_vm_t *vm, u_char *key, size_t size,
292+
size_t length, uint32_t hash);
291293

292294

293295
const njs_lexer_keyword_entry_t *njs_lexer_keyword(const u_char *key,

0 commit comments

Comments
 (0)