1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
3 * ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
16 * The Original Code is Mozilla Communicator client code, released
19 * The Initial Developer of the Original Code is
20 * Netscape Communications Corporation.
21 * Portions created by the Initial Developer are Copyright (C) 1998
22 * the Initial Developer. All Rights Reserved.
26 * Alternatively, the contents of this file may be used under the terms of
27 * either of the GNU General Public License Version 2 or later (the "GPL"),
28 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
46 #include "jsversion.h"
48 #include "jshash.h" /* Added by JSIFY */
57 #define ATOM_PINNED 0x1 /* atom is pinned against GC */
58 #define ATOM_INTERNED 0x2 /* pinned variant for JS_Intern* API */
59 #define ATOM_NOCOPY 0x4 /* don't copy atom string bytes */
60 #define ATOM_TMPSTR 0x8 /* internal, to avoid extra string */
62 #define ATOM_KEY(atom) ((jsval)(atom))
63 #define ATOM_IS_DOUBLE(atom) JSVAL_IS_DOUBLE(ATOM_KEY(atom))
64 #define ATOM_TO_DOUBLE(atom) JSVAL_TO_DOUBLE(ATOM_KEY(atom))
65 #define ATOM_IS_STRING(atom) JSVAL_IS_STRING(ATOM_KEY(atom))
66 #define ATOM_TO_STRING(atom) JSVAL_TO_STRING(ATOM_KEY(atom))
68 JS_STATIC_ASSERT(sizeof(JSHashNumber
) == 4);
69 JS_STATIC_ASSERT(sizeof(JSAtom
*) == JS_BYTES_PER_WORD
);
71 #if JS_BYTES_PER_WORD == 4
72 # define ATOM_HASH(atom) ((JSHashNumber)(atom) >> 2)
73 #elif JS_BYTES_PER_WORD == 8
74 # define ATOM_HASH(atom) (((JSHashNumber)(jsuword)(atom) >> 3) ^ \
75 (JSHashNumber)((jsuword)(atom) >> 32))
77 # error "Unsupported configuration"
81 * Return a printable, lossless char[] representation of a string-type atom.
82 * The lifetime of the result extends at least until the next GC activation,
83 * longer if cx's string newborn root is not overwritten.
86 js_AtomToPrintableString(JSContext
*cx
, JSAtom
*atom
);
88 struct JSAtomListElement
{
92 #define ALE_ATOM(ale) ((JSAtom *) (ale)->entry.key)
93 #define ALE_INDEX(ale) ((jsatomid) JS_PTR_TO_UINT32((ale)->entry.value))
94 #define ALE_JSOP(ale) ((JSOp) JS_PTR_TO_UINT32((ale)->entry.value))
95 #define ALE_VALUE(ale) ((jsval) (ale)->entry.value)
96 #define ALE_NEXT(ale) ((JSAtomListElement *) (ale)->entry.next)
98 #define ALE_SET_ATOM(ale,atom) ((ale)->entry.key = (const void *)(atom))
99 #define ALE_SET_INDEX(ale,index)((ale)->entry.value = JS_UINT32_TO_PTR(index))
100 #define ALE_SET_JSOP(ale,op) ((ale)->entry.value = JS_UINT32_TO_PTR(op))
101 #define ALE_SET_VALUE(ale, v) ((ale)->entry.value = (void *)(v))
104 JSHashEntry
*list
; /* literals indexed for mapping */
105 JSHashTable
*table
; /* hash table if list gets too long */
106 jsuint count
; /* count of indexed literals */
109 #define ATOM_LIST_INIT(al) ((al)->list = NULL, (al)->table = NULL, \
112 #define ATOM_LIST_SEARCH(_ale,_al,_atom) \
114 JSHashEntry **_hep; \
115 ATOM_LIST_LOOKUP(_ale, _hep, _al, _atom); \
118 #define ATOM_LIST_LOOKUP(_ale,_hep,_al,_atom) \
120 if ((_al)->table) { \
121 _hep = JS_HashTableRawLookup((_al)->table, ATOM_HASH(_atom), \
123 _ale = *_hep ? (JSAtomListElement *) *_hep : NULL; \
125 JSHashEntry **_alep = &(_al)->list; \
127 while ((_ale = (JSAtomListElement *)*_alep) != NULL) { \
128 if (ALE_ATOM(_ale) == (_atom)) { \
129 /* Hit, move atom's element to the front of the list. */ \
130 *_alep = (_ale)->entry.next; \
131 (_ale)->entry.next = (_al)->list; \
132 (_al)->list = &_ale->entry; \
135 _alep = &_ale->entry.next; \
141 JSAtom
**vector
; /* array of ptrs to indexed atoms */
142 jsatomid length
; /* count of (to-be-)indexed atoms */
146 JSDHashTable stringAtoms
; /* hash table with shared strings */
147 JSDHashTable doubleAtoms
; /* hash table with shared doubles */
153 * From this point until the end of struct definition the struct must
154 * contain only JSAtom fields. We use this to access the storage occupied
155 * by the common atoms in js_FinishCommonAtoms.
157 * js_common_atom_names defined in jsatom.c contains C strings for atoms
158 * in the order of atom fields here. Therefore you must update that array
159 * if you change member order here.
162 /* The rt->emptyString atom, see jsstr.c's js_InitRuntimeStringState. */
165 /* Type names and value literals. */
166 JSAtom
*typeAtoms
[JSTYPE_LIMIT
];
167 JSAtom
*booleanAtoms
[2];
170 /* Standard class constructor or prototype names. */
171 JSAtom
*classAtoms
[JSProto_LIMIT
];
173 /* Various built-in or commonly-used atoms, pinned on first context. */
174 JSAtom
*anonymousAtom
;
175 JSAtom
*argumentsAtom
;
179 JSAtom
*classPrototypeAtom
;
180 JSAtom
*constructorAtom
;
184 JSAtom
*fileNameAtom
;
189 JSAtom
*iteratorAtom
;
191 JSAtom
*lineNumberAtom
;
195 JSAtom
*noSuchMethodAtom
;
201 JSAtom
*toLocaleStringAtom
;
202 JSAtom
*toSourceAtom
;
203 JSAtom
*toStringAtom
;
208 #if JS_HAS_XML_SUPPORT
210 JSAtom
*namespaceAtom
;
212 JSAtom
*qualifierAtom
;
216 JSAtom
*starQualifierAtom
;
223 JSAtom
*constructAtom
;
224 JSAtom
*hasInstanceAtom
;
225 JSAtom
*ExecutionContextAtom
;
229 /* Less frequently used atoms, pinned lazily by JS_ResolveStandardClass. */
231 JSAtom
*InfinityAtom
;
234 JSAtom
*decodeURIAtom
;
235 JSAtom
*decodeURIComponentAtom
;
236 JSAtom
*defineGetterAtom
;
237 JSAtom
*defineSetterAtom
;
238 JSAtom
*encodeURIAtom
;
239 JSAtom
*encodeURIComponentAtom
;
241 JSAtom
*functionNamespaceURIAtom
;
242 JSAtom
*hasOwnPropertyAtom
;
243 JSAtom
*isFiniteAtom
;
245 JSAtom
*isPrototypeOfAtom
;
246 JSAtom
*isXMLNameAtom
;
247 JSAtom
*lookupGetterAtom
;
248 JSAtom
*lookupSetterAtom
;
249 JSAtom
*parseFloatAtom
;
250 JSAtom
*parseIntAtom
;
251 JSAtom
*propertyIsEnumerableAtom
;
252 JSAtom
*unescapeAtom
;
259 #define ATOM_OFFSET_START offsetof(JSAtomState, emptyAtom)
260 #define LAZY_ATOM_OFFSET_START offsetof(JSAtomState, lazy)
261 #define ATOM_OFFSET_LIMIT (sizeof(JSAtomState))
263 #define COMMON_ATOMS_START(state) \
264 (JSAtom **)((uint8 *)(state) + ATOM_OFFSET_START)
266 /* Start and limit offsets should correspond to atoms. */
267 JS_STATIC_ASSERT(ATOM_OFFSET_START
% sizeof(JSAtom
*) == 0);
268 JS_STATIC_ASSERT(ATOM_OFFSET_LIMIT
% sizeof(JSAtom
*) == 0);
270 #define ATOM_OFFSET(name) offsetof(JSAtomState, name##Atom)
271 #define OFFSET_TO_ATOM(rt,off) (*(JSAtom **)((char*)&(rt)->atomState + (off)))
272 #define CLASS_ATOM_OFFSET(name) offsetof(JSAtomState,classAtoms[JSProto_##name])
274 #define CLASS_ATOM(cx,name) \
275 ((cx)->runtime->atomState.classAtoms[JSProto_##name])
277 extern const char *const js_common_atom_names
[];
280 * Macros to access C strings for JSType and boolean literals together with
281 * checks that type names and booleans starts from index 1 and 1+JSTYPE_LIMIT
284 #define JS_TYPE_STR(type) (js_common_atom_names[1 + (type)])
285 #define JS_BOOLEAN_STR(type) (js_common_atom_names[1 + JSTYPE_LIMIT + (type)])
287 JS_STATIC_ASSERT(1 * sizeof(JSAtom
*) ==
288 offsetof(JSAtomState
, typeAtoms
) - ATOM_OFFSET_START
);
289 JS_STATIC_ASSERT((1 + JSTYPE_LIMIT
) * sizeof(JSAtom
*) ==
290 offsetof(JSAtomState
, booleanAtoms
) - ATOM_OFFSET_START
);
292 /* Well-known predefined C strings. */
293 #define JS_PROTO(name,code,init) extern const char js_##name##_str[];
294 #include "jsproto.tbl"
297 extern const char js_anonymous_str
[];
298 extern const char js_arguments_str
[];
299 extern const char js_arity_str
[];
300 extern const char js_callee_str
[];
301 extern const char js_caller_str
[];
302 extern const char js_class_prototype_str
[];
303 extern const char js_close_str
[];
304 extern const char js_constructor_str
[];
305 extern const char js_count_str
[];
306 extern const char js_etago_str
[];
307 extern const char js_each_str
[];
308 extern const char js_eval_str
[];
309 extern const char js_fileName_str
[];
310 extern const char js_get_str
[];
311 extern const char js_getter_str
[];
312 extern const char js_index_str
[];
313 extern const char js_input_str
[];
314 extern const char js_iterator_str
[];
315 extern const char js_length_str
[];
316 extern const char js_lineNumber_str
[];
317 extern const char js_message_str
[];
318 extern const char js_name_str
[];
319 extern const char js_namespace_str
[];
320 extern const char js_next_str
[];
321 extern const char js_noSuchMethod_str
[];
322 extern const char js_object_str
[];
323 extern const char js_parent_str
[];
324 extern const char js_proto_str
[];
325 extern const char js_ptagc_str
[];
326 extern const char js_qualifier_str
[];
327 extern const char js_send_str
[];
328 extern const char js_setter_str
[];
329 extern const char js_set_str
[];
330 extern const char js_space_str
[];
331 extern const char js_stack_str
[];
332 extern const char js_stago_str
[];
333 extern const char js_star_str
[];
334 extern const char js_starQualifier_str
[];
335 extern const char js_tagc_str
[];
336 extern const char js_toSource_str
[];
337 extern const char js_toString_str
[];
338 extern const char js_toLocaleString_str
[];
339 extern const char js_undefined_str
[];
340 extern const char js_valueOf_str
[];
341 extern const char js_toJSON_str
[];
342 extern const char js_xml_str
[];
345 extern const char js_call_str
[];
346 extern const char js_construct_str
[];
347 extern const char js_hasInstance_str
[];
348 extern const char js_ExecutionContext_str
[];
349 extern const char js_current_str
[];
353 * Initialize atom state. Return true on success, false on failure to allocate
354 * memory. The caller must zero rt->atomState before calling this function and
355 * only call it after js_InitGC successfully returns.
358 js_InitAtomState(JSRuntime
*rt
);
361 * Free and clear atom state including any interned string atoms. This
362 * function must be called before js_FinishGC.
365 js_FinishAtomState(JSRuntime
*rt
);
368 * Atom tracing and garbage collection hooks.
372 js_TraceAtomState(JSTracer
*trc
, JSBool allAtoms
);
375 js_SweepAtomState(JSContext
*cx
);
378 js_InitCommonAtoms(JSContext
*cx
);
381 js_FinishCommonAtoms(JSContext
*cx
);
384 * Find or create the atom for a double value. Return null on failure to
388 js_AtomizeDouble(JSContext
*cx
, jsdouble d
);
391 * Find or create the atom for a string. Return null on failure to allocate
395 js_AtomizeString(JSContext
*cx
, JSString
*str
, uintN flags
);
398 js_Atomize(JSContext
*cx
, const char *bytes
, size_t length
, uintN flags
);
401 js_AtomizeChars(JSContext
*cx
, const jschar
*chars
, size_t length
, uintN flags
);
404 * Return an existing atom for the given char array or null if the char
405 * sequence is currently not atomized.
408 js_GetExistingStringAtom(JSContext
*cx
, const jschar
*chars
, size_t length
);
411 * This variant handles all primitive values.
414 js_AtomizePrimitiveValue(JSContext
*cx
, jsval v
, JSAtom
**atomp
);
417 * Convert v to an atomized string and wrap it as an id.
420 js_ValueToStringId(JSContext
*cx
, jsval v
, jsid
*idp
);
424 extern JS_FRIEND_API(void)
425 js_DumpAtoms(JSContext
*cx
, FILE *fp
);
430 * Assign atom an index and insert it on al.
432 extern JSAtomListElement
*
433 js_IndexAtom(JSContext
*cx
, JSAtom
*atom
, JSAtomList
*al
);
436 * For all unmapped atoms recorded in al, add a mapping from the atom's index
437 * to its address. map->length must already be set to the number of atoms in
438 * the list and map->vector must point to pre-allocated memory.
441 js_InitAtomMap(JSContext
*cx
, JSAtomMap
*map
, JSAtomList
*al
);
445 #endif /* jsatom_h___ */