|
|
1.1 ! root 1: /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- ! 2: * ! 3: * ***** BEGIN LICENSE BLOCK ***** ! 4: * Version: MPL 1.1/GPL 2.0/LGPL 2.1 ! 5: * ! 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/ ! 10: * ! 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 ! 14: * License. ! 15: * ! 16: * The Original Code is Mozilla Communicator client code, released ! 17: * March 31, 1998. ! 18: * ! 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. ! 23: * ! 24: * Contributor(s): ! 25: * ! 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. ! 37: * ! 38: * ***** END LICENSE BLOCK ***** */ ! 39: ! 40: #ifndef jsatom_h___ ! 41: #define jsatom_h___ ! 42: /* ! 43: * JS atom table. ! 44: */ ! 45: #include <stddef.h> ! 46: #include "jstypes.h" ! 47: #include "jshash.h" /* Added by JSIFY */ ! 48: #include "jsapi.h" ! 49: #include "jsprvtd.h" ! 50: #include "jspubtd.h" ! 51: ! 52: #ifdef JS_THREADSAFE ! 53: #include "jslock.h" ! 54: #endif ! 55: ! 56: JS_BEGIN_EXTERN_C ! 57: ! 58: #define ATOM_PINNED 0x01 /* atom is pinned against GC */ ! 59: #define ATOM_INTERNED 0x02 /* pinned variant for JS_Intern* API */ ! 60: #define ATOM_MARK 0x04 /* atom is reachable via GC */ ! 61: #define ATOM_NOCOPY 0x40 /* don't copy atom string bytes */ ! 62: #define ATOM_TMPSTR 0x80 /* internal, to avoid extra string */ ! 63: ! 64: struct JSAtom { ! 65: JSHashEntry entry; /* key is jsval, value keyword info */ ! 66: uint32 flags; /* pinned, interned, and mark flags */ ! 67: jsatomid number; /* atom serial number and hash code */ ! 68: }; ! 69: ! 70: #define ATOM_KEY(atom) ((jsval)(atom)->entry.key) ! 71: #define ATOM_IS_OBJECT(atom) JSVAL_IS_OBJECT(ATOM_KEY(atom)) ! 72: #define ATOM_TO_OBJECT(atom) JSVAL_TO_OBJECT(ATOM_KEY(atom)) ! 73: #define ATOM_IS_INT(atom) JSVAL_IS_INT(ATOM_KEY(atom)) ! 74: #define ATOM_TO_INT(atom) JSVAL_TO_INT(ATOM_KEY(atom)) ! 75: #define ATOM_IS_DOUBLE(atom) JSVAL_IS_DOUBLE(ATOM_KEY(atom)) ! 76: #define ATOM_TO_DOUBLE(atom) JSVAL_TO_DOUBLE(ATOM_KEY(atom)) ! 77: #define ATOM_IS_STRING(atom) JSVAL_IS_STRING(ATOM_KEY(atom)) ! 78: #define ATOM_TO_STRING(atom) JSVAL_TO_STRING(ATOM_KEY(atom)) ! 79: #define ATOM_IS_BOOLEAN(atom) JSVAL_IS_BOOLEAN(ATOM_KEY(atom)) ! 80: #define ATOM_TO_BOOLEAN(atom) JSVAL_TO_BOOLEAN(ATOM_KEY(atom)) ! 81: ! 82: /* ! 83: * Return a printable, lossless char[] representation of a string-type atom. ! 84: * The lifetime of the result extends at least until the next GC activation, ! 85: * longer if cx's string newborn root is not overwritten. ! 86: */ ! 87: extern JS_FRIEND_API(const char *) ! 88: js_AtomToPrintableString(JSContext *cx, JSAtom *atom); ! 89: ! 90: #define ATOM_KEYWORD(atom) ((struct keyword *)(atom)->entry.value) ! 91: #define ATOM_SET_KEYWORD(atom,kw) ((atom)->entry.value = (kw)) ! 92: ! 93: struct JSAtomListElement { ! 94: JSHashEntry entry; ! 95: }; ! 96: ! 97: #define ALE_ATOM(ale) ((JSAtom *) (ale)->entry.key) ! 98: #define ALE_INDEX(ale) ((jsatomid) (ale)->entry.value) ! 99: #define ALE_JSOP(ale) ((JSOp) (ale)->entry.value) ! 100: #define ALE_VALUE(ale) ((jsval) (ale)->entry.value) ! 101: #define ALE_NEXT(ale) ((JSAtomListElement *) (ale)->entry.next) ! 102: ! 103: #define ALE_SET_ATOM(ale,atom) ((ale)->entry.key = (const void *)(atom)) ! 104: #define ALE_SET_INDEX(ale,index)((ale)->entry.value = (void *)(index)) ! 105: #define ALE_SET_JSOP(ale,op) ((ale)->entry.value = (void *)(op)) ! 106: #define ALE_SET_VALUE(ale,val) ((ale)->entry.value = (JSHashEntry *)(val)) ! 107: #define ALE_SET_NEXT(ale,link) ((ale)->entry.next = (JSHashEntry *)(link)) ! 108: ! 109: struct JSAtomList { ! 110: JSAtomListElement *list; /* literals indexed for mapping */ ! 111: JSHashTable *table; /* hash table if list gets too long */ ! 112: jsuint count; /* count of indexed literals */ ! 113: }; ! 114: ! 115: #define ATOM_LIST_INIT(al) ((al)->list = NULL, (al)->table = NULL, \ ! 116: (al)->count = 0) ! 117: ! 118: #define ATOM_LIST_SEARCH(_ale,_al,_atom) \ ! 119: JS_BEGIN_MACRO \ ! 120: JSHashEntry **_hep; \ ! 121: ATOM_LIST_LOOKUP(_ale, _hep, _al, _atom); \ ! 122: JS_END_MACRO ! 123: ! 124: #define ATOM_LIST_LOOKUP(_ale,_hep,_al,_atom) \ ! 125: JS_BEGIN_MACRO \ ! 126: if ((_al)->table) { \ ! 127: _hep = JS_HashTableRawLookup((_al)->table, _atom->number, _atom); \ ! 128: _ale = *_hep ? (JSAtomListElement *) *_hep : NULL; \ ! 129: } else { \ ! 130: JSAtomListElement **_alep = &(_al)->list; \ ! 131: _hep = NULL; \ ! 132: while ((_ale = *_alep) != NULL) { \ ! 133: if (ALE_ATOM(_ale) == (_atom)) { \ ! 134: /* Hit, move atom's element to the front of the list. */ \ ! 135: *_alep = ALE_NEXT(_ale); \ ! 136: ALE_SET_NEXT(_ale, (_al)->list); \ ! 137: (_al)->list = _ale; \ ! 138: break; \ ! 139: } \ ! 140: _alep = (JSAtomListElement **)&_ale->entry.next; \ ! 141: } \ ! 142: } \ ! 143: JS_END_MACRO ! 144: ! 145: struct JSAtomMap { ! 146: JSAtom **vector; /* array of ptrs to indexed atoms */ ! 147: jsatomid length; /* count of (to-be-)indexed atoms */ ! 148: }; ! 149: ! 150: struct JSAtomState { ! 151: JSRuntime *runtime; /* runtime that owns us */ ! 152: JSHashTable *table; /* hash table containing all atoms */ ! 153: jsatomid number; /* one beyond greatest atom number */ ! 154: jsatomid liveAtoms; /* number of live atoms after last GC */ ! 155: ! 156: /* Type names and value literals. */ ! 157: JSAtom *typeAtoms[JSTYPE_LIMIT]; ! 158: JSAtom *booleanAtoms[2]; ! 159: JSAtom *nullAtom; ! 160: ! 161: /* Various built-in or commonly-used atoms, pinned on first context. */ ! 162: JSAtom *ArgumentsAtom; ! 163: JSAtom *ArrayAtom; ! 164: JSAtom *BooleanAtom; ! 165: JSAtom *CallAtom; ! 166: JSAtom *DateAtom; ! 167: JSAtom *ErrorAtom; ! 168: JSAtom *FunctionAtom; ! 169: JSAtom *MathAtom; ! 170: JSAtom *NumberAtom; ! 171: JSAtom *ObjectAtom; ! 172: JSAtom *RegExpAtom; ! 173: JSAtom *ScriptAtom; ! 174: JSAtom *StringAtom; ! 175: JSAtom *anonymousAtom; ! 176: JSAtom *argumentsAtom; ! 177: JSAtom *arityAtom; ! 178: JSAtom *calleeAtom; ! 179: JSAtom *callerAtom; ! 180: JSAtom *classPrototypeAtom; ! 181: JSAtom *constructorAtom; ! 182: JSAtom *countAtom; ! 183: JSAtom *evalAtom; ! 184: JSAtom *getAtom; ! 185: JSAtom *getterAtom; ! 186: JSAtom *indexAtom; ! 187: JSAtom *inputAtom; ! 188: JSAtom *lengthAtom; ! 189: JSAtom *nameAtom; ! 190: JSAtom *noSuchMethodAtom; ! 191: JSAtom *parentAtom; ! 192: JSAtom *protoAtom; ! 193: JSAtom *setAtom; ! 194: JSAtom *setterAtom; ! 195: JSAtom *toLocaleStringAtom; ! 196: JSAtom *toSourceAtom; ! 197: JSAtom *toStringAtom; ! 198: JSAtom *valueOfAtom; ! 199: ! 200: /* Less frequently used atoms, pinned lazily by JS_ResolveStandardClass. */ ! 201: struct { ! 202: JSAtom *EvalErrorAtom; ! 203: JSAtom *InfinityAtom; ! 204: JSAtom *InternalErrorAtom; ! 205: JSAtom *NaNAtom; ! 206: JSAtom *RangeErrorAtom; ! 207: JSAtom *ReferenceErrorAtom; ! 208: JSAtom *SyntaxErrorAtom; ! 209: JSAtom *TypeErrorAtom; ! 210: JSAtom *URIErrorAtom; ! 211: JSAtom *decodeURIAtom; ! 212: JSAtom *decodeURIComponentAtom; ! 213: JSAtom *defineGetterAtom; ! 214: JSAtom *defineSetterAtom; ! 215: JSAtom *encodeURIAtom; ! 216: JSAtom *encodeURIComponentAtom; ! 217: JSAtom *escapeAtom; ! 218: JSAtom *hasOwnPropertyAtom; ! 219: JSAtom *isFiniteAtom; ! 220: JSAtom *isNaNAtom; ! 221: JSAtom *isPrototypeOfAtom; ! 222: JSAtom *lookupGetterAtom; ! 223: JSAtom *lookupSetterAtom; ! 224: JSAtom *parseFloatAtom; ! 225: JSAtom *parseIntAtom; ! 226: JSAtom *propertyIsEnumerableAtom; ! 227: JSAtom *unescapeAtom; ! 228: JSAtom *unevalAtom; ! 229: JSAtom *unwatchAtom; ! 230: JSAtom *watchAtom; ! 231: } lazy; ! 232: ! 233: #ifdef JS_THREADSAFE ! 234: JSThinLock lock; ! 235: volatile uint32 tablegen; ! 236: #endif ! 237: #ifdef NARCISSUS ! 238: JSAtom *callAtom; ! 239: JSAtom *constructAtom; ! 240: JSAtom *hasInstanceAtom; ! 241: JSAtom *ExecutionContextAtom; ! 242: JSAtom *currentAtom; ! 243: #endif ! 244: }; ! 245: ! 246: /* Well-known predefined strings and their atoms. */ ! 247: extern const char *js_type_str[]; ! 248: extern const char *js_boolean_str[]; ! 249: ! 250: extern const char js_Arguments_str[]; ! 251: extern const char js_Array_str[]; ! 252: extern const char js_Boolean_str[]; ! 253: extern const char js_Call_str[]; ! 254: extern const char js_Date_str[]; ! 255: extern const char js_Function_str[]; ! 256: extern const char js_Math_str[]; ! 257: extern const char js_Number_str[]; ! 258: extern const char js_Object_str[]; ! 259: extern const char js_RegExp_str[]; ! 260: extern const char js_Script_str[]; ! 261: extern const char js_String_str[]; ! 262: extern const char js_anonymous_str[]; ! 263: extern const char js_arguments_str[]; ! 264: extern const char js_arity_str[]; ! 265: extern const char js_callee_str[]; ! 266: extern const char js_caller_str[]; ! 267: extern const char js_class_prototype_str[]; ! 268: extern const char js_constructor_str[]; ! 269: extern const char js_count_str[]; ! 270: extern const char js_eval_str[]; ! 271: extern const char js_getter_str[]; ! 272: extern const char js_get_str[]; ! 273: extern const char js_index_str[]; ! 274: extern const char js_input_str[]; ! 275: extern const char js_length_str[]; ! 276: extern const char js_name_str[]; ! 277: extern const char js_noSuchMethod_str[]; ! 278: extern const char js_parent_str[]; ! 279: extern const char js_proto_str[]; ! 280: extern const char js_setter_str[]; ! 281: extern const char js_set_str[]; ! 282: extern const char js_toSource_str[]; ! 283: extern const char js_toString_str[]; ! 284: extern const char js_toLocaleString_str[]; ! 285: extern const char js_valueOf_str[]; ! 286: ! 287: #ifdef NARCISSUS ! 288: extern const char js_call_str[]; ! 289: extern const char js_construct_str[]; ! 290: extern const char js_hasInstance_str[]; ! 291: extern const char js_ExecutionContext_str[]; ! 292: extern const char js_current_str[]; ! 293: #endif ! 294: ! 295: /* ! 296: * Initialize atom state. Return true on success, false with an out of ! 297: * memory error report on failure. ! 298: */ ! 299: extern JSBool ! 300: js_InitAtomState(JSContext *cx, JSAtomState *state); ! 301: ! 302: /* ! 303: * Free and clear atom state (except for any interned string atoms). ! 304: */ ! 305: extern void ! 306: js_FreeAtomState(JSContext *cx, JSAtomState *state); ! 307: ! 308: /* ! 309: * Interned strings are atoms that live until state's runtime is destroyed. ! 310: * This function frees all interned string atoms, and then frees and clears ! 311: * state's members (just as js_FreeAtomState does), unless there aren't any ! 312: * interned strings in state -- in which case state must be "free" already. ! 313: * ! 314: * NB: js_FreeAtomState is called for each "last" context being destroyed in ! 315: * a runtime, where there may yet be another context created in the runtime; ! 316: * whereas js_FinishAtomState is called from JS_DestroyRuntime, when we know ! 317: * that no more contexts will be created. Thus we minimize garbage during ! 318: * context-free episodes on a runtime, while preserving atoms created by the ! 319: * JS_Intern*String APIs for the life of the runtime. ! 320: */ ! 321: extern void ! 322: js_FinishAtomState(JSAtomState *state); ! 323: ! 324: /* ! 325: * Atom garbage collection hooks. ! 326: */ ! 327: typedef void ! 328: (*JSGCThingMarker)(void *thing, void *data); ! 329: ! 330: extern void ! 331: js_MarkAtomState(JSAtomState *state, uintN gcflags, JSGCThingMarker mark, ! 332: void *data); ! 333: ! 334: extern void ! 335: js_SweepAtomState(JSAtomState *state); ! 336: ! 337: extern JSBool ! 338: js_InitPinnedAtoms(JSContext *cx, JSAtomState *state); ! 339: ! 340: extern void ! 341: js_UnpinPinnedAtoms(JSAtomState *state); ! 342: ! 343: /* ! 344: * Find or create the atom for an object. If we create a new atom, give it the ! 345: * type indicated in flags. Return 0 on failure to allocate memory. ! 346: */ ! 347: extern JSAtom * ! 348: js_AtomizeObject(JSContext *cx, JSObject *obj, uintN flags); ! 349: ! 350: /* ! 351: * Find or create the atom for a Boolean value. If we create a new atom, give ! 352: * it the type indicated in flags. Return 0 on failure to allocate memory. ! 353: */ ! 354: extern JSAtom * ! 355: js_AtomizeBoolean(JSContext *cx, JSBool b, uintN flags); ! 356: ! 357: /* ! 358: * Find or create the atom for an integer value. If we create a new atom, give ! 359: * it the type indicated in flags. Return 0 on failure to allocate memory. ! 360: */ ! 361: extern JSAtom * ! 362: js_AtomizeInt(JSContext *cx, jsint i, uintN flags); ! 363: ! 364: /* ! 365: * Find or create the atom for a double value. If we create a new atom, give ! 366: * it the type indicated in flags. Return 0 on failure to allocate memory. ! 367: */ ! 368: extern JSAtom * ! 369: js_AtomizeDouble(JSContext *cx, jsdouble d, uintN flags); ! 370: ! 371: /* ! 372: * Find or create the atom for a string. If we create a new atom, give it the ! 373: * type indicated in flags. Return 0 on failure to allocate memory. ! 374: */ ! 375: extern JSAtom * ! 376: js_AtomizeString(JSContext *cx, JSString *str, uintN flags); ! 377: ! 378: extern JS_FRIEND_API(JSAtom *) ! 379: js_Atomize(JSContext *cx, const char *bytes, size_t length, uintN flags); ! 380: ! 381: extern JS_FRIEND_API(JSAtom *) ! 382: js_AtomizeChars(JSContext *cx, const jschar *chars, size_t length, uintN flags); ! 383: ! 384: /* ! 385: * This variant handles all value tag types. ! 386: */ ! 387: extern JSAtom * ! 388: js_AtomizeValue(JSContext *cx, jsval value, uintN flags); ! 389: ! 390: /* ! 391: * Convert v to an atomized string. ! 392: */ ! 393: extern JSAtom * ! 394: js_ValueToStringAtom(JSContext *cx, jsval v); ! 395: ! 396: /* ! 397: * Assign atom an index and insert it on al. ! 398: */ ! 399: extern JSAtomListElement * ! 400: js_IndexAtom(JSContext *cx, JSAtom *atom, JSAtomList *al); ! 401: ! 402: /* ! 403: * Get the atom with index i from map. ! 404: */ ! 405: extern JS_FRIEND_API(JSAtom *) ! 406: js_GetAtom(JSContext *cx, JSAtomMap *map, jsatomid i); ! 407: ! 408: /* ! 409: * For all unmapped atoms recorded in al, add a mapping from the atom's index ! 410: * to its address. The GC must not run until all indexed atoms in atomLists ! 411: * have been mapped by scripts connected to live objects (Function and Script ! 412: * class objects have scripts as/in their private data -- the GC knows about ! 413: * these two classes). ! 414: */ ! 415: extern JS_FRIEND_API(JSBool) ! 416: js_InitAtomMap(JSContext *cx, JSAtomMap *map, JSAtomList *al); ! 417: ! 418: /* ! 419: * Free map->vector and clear map. ! 420: */ ! 421: extern JS_FRIEND_API(void) ! 422: js_FreeAtomMap(JSContext *cx, JSAtomMap *map); ! 423: ! 424: JS_END_EXTERN_C ! 425: ! 426: #endif /* jsatom_h___ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.