@@ -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+ }
0 commit comments