|
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
|
2 * vim: set ts=8 sts=4 et sw=4 tw=99: |
|
3 * This Source Code Form is subject to the terms of the Mozilla Public |
|
4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 |
|
7 #ifndef jsatom_h |
|
8 #define jsatom_h |
|
9 |
|
10 #include "mozilla/HashFunctions.h" |
|
11 |
|
12 #include "jsalloc.h" |
|
13 |
|
14 #include "gc/Barrier.h" |
|
15 #include "gc/Rooting.h" |
|
16 #include "vm/CommonPropertyNames.h" |
|
17 |
|
18 class JSAtom; |
|
19 class JSAutoByteString; |
|
20 |
|
21 struct JSIdArray { |
|
22 int length; |
|
23 js::HeapId vector[1]; /* actually, length jsid words */ |
|
24 }; |
|
25 |
|
26 namespace js { |
|
27 |
|
28 JS_STATIC_ASSERT(sizeof(HashNumber) == 4); |
|
29 |
|
30 static MOZ_ALWAYS_INLINE js::HashNumber |
|
31 HashId(jsid id) |
|
32 { |
|
33 return mozilla::HashGeneric(JSID_BITS(id)); |
|
34 } |
|
35 |
|
36 struct JsidHasher |
|
37 { |
|
38 typedef jsid Lookup; |
|
39 static HashNumber hash(const Lookup &l) { |
|
40 return HashNumber(JSID_BITS(l)); |
|
41 } |
|
42 static bool match(const jsid &id, const Lookup &l) { |
|
43 return id == l; |
|
44 } |
|
45 }; |
|
46 |
|
47 /* |
|
48 * Return a printable, lossless char[] representation of a string-type atom. |
|
49 * The lifetime of the result matches the lifetime of bytes. |
|
50 */ |
|
51 extern const char * |
|
52 AtomToPrintableString(ExclusiveContext *cx, JSAtom *atom, JSAutoByteString *bytes); |
|
53 |
|
54 class AtomStateEntry |
|
55 { |
|
56 uintptr_t bits; |
|
57 |
|
58 static const uintptr_t NO_TAG_MASK = uintptr_t(-1) - 1; |
|
59 |
|
60 public: |
|
61 AtomStateEntry() : bits(0) {} |
|
62 AtomStateEntry(const AtomStateEntry &other) : bits(other.bits) {} |
|
63 AtomStateEntry(JSAtom *ptr, bool tagged) |
|
64 : bits(uintptr_t(ptr) | uintptr_t(tagged)) |
|
65 { |
|
66 JS_ASSERT((uintptr_t(ptr) & 0x1) == 0); |
|
67 } |
|
68 |
|
69 bool isTagged() const { |
|
70 return bits & 0x1; |
|
71 } |
|
72 |
|
73 /* |
|
74 * Non-branching code sequence. Note that the const_cast is safe because |
|
75 * the hash function doesn't consider the tag to be a portion of the key. |
|
76 */ |
|
77 void setTagged(bool enabled) const { |
|
78 const_cast<AtomStateEntry *>(this)->bits |= uintptr_t(enabled); |
|
79 } |
|
80 |
|
81 JSAtom *asPtr() const; |
|
82 }; |
|
83 |
|
84 struct AtomHasher |
|
85 { |
|
86 struct Lookup |
|
87 { |
|
88 const jschar *chars; |
|
89 size_t length; |
|
90 const JSAtom *atom; /* Optional. */ |
|
91 |
|
92 HashNumber hash; |
|
93 |
|
94 Lookup(const jschar *chars, size_t length) |
|
95 : chars(chars), length(length), atom(nullptr) |
|
96 { |
|
97 hash = mozilla::HashString(chars, length); |
|
98 } |
|
99 inline Lookup(const JSAtom *atom); |
|
100 }; |
|
101 |
|
102 static HashNumber hash(const Lookup &l) { return l.hash; } |
|
103 static inline bool match(const AtomStateEntry &entry, const Lookup &lookup); |
|
104 static void rekey(AtomStateEntry &k, const AtomStateEntry& newKey) { k = newKey; } |
|
105 }; |
|
106 |
|
107 typedef HashSet<AtomStateEntry, AtomHasher, SystemAllocPolicy> AtomSet; |
|
108 |
|
109 class PropertyName; |
|
110 |
|
111 } /* namespace js */ |
|
112 |
|
113 extern bool |
|
114 AtomIsInterned(JSContext *cx, JSAtom *atom); |
|
115 |
|
116 /* Well-known predefined C strings. */ |
|
117 #define DECLARE_PROTO_STR(name,code,init,clasp) extern const char js_##name##_str[]; |
|
118 JS_FOR_EACH_PROTOTYPE(DECLARE_PROTO_STR) |
|
119 #undef DECLARE_PROTO_STR |
|
120 |
|
121 #define DECLARE_CONST_CHAR_STR(idpart, id, text) extern const char js_##idpart##_str[]; |
|
122 FOR_EACH_COMMON_PROPERTYNAME(DECLARE_CONST_CHAR_STR) |
|
123 #undef DECLARE_CONST_CHAR_STR |
|
124 |
|
125 /* Constant strings that are not atomized. */ |
|
126 extern const char js_break_str[]; |
|
127 extern const char js_case_str[]; |
|
128 extern const char js_catch_str[]; |
|
129 extern const char js_class_str[]; |
|
130 extern const char js_close_str[]; |
|
131 extern const char js_const_str[]; |
|
132 extern const char js_continue_str[]; |
|
133 extern const char js_debugger_str[]; |
|
134 extern const char js_default_str[]; |
|
135 extern const char js_do_str[]; |
|
136 extern const char js_else_str[]; |
|
137 extern const char js_enum_str[]; |
|
138 extern const char js_export_str[]; |
|
139 extern const char js_extends_str[]; |
|
140 extern const char js_finally_str[]; |
|
141 extern const char js_for_str[]; |
|
142 extern const char js_getter_str[]; |
|
143 extern const char js_if_str[]; |
|
144 extern const char js_implements_str[]; |
|
145 extern const char js_import_str[]; |
|
146 extern const char js_in_str[]; |
|
147 extern const char js_instanceof_str[]; |
|
148 extern const char js_interface_str[]; |
|
149 extern const char js_new_str[]; |
|
150 extern const char js_package_str[]; |
|
151 extern const char js_private_str[]; |
|
152 extern const char js_protected_str[]; |
|
153 extern const char js_public_str[]; |
|
154 extern const char js_send_str[]; |
|
155 extern const char js_setter_str[]; |
|
156 extern const char js_static_str[]; |
|
157 extern const char js_super_str[]; |
|
158 extern const char js_switch_str[]; |
|
159 extern const char js_this_str[]; |
|
160 extern const char js_try_str[]; |
|
161 extern const char js_typeof_str[]; |
|
162 extern const char js_void_str[]; |
|
163 extern const char js_while_str[]; |
|
164 extern const char js_with_str[]; |
|
165 |
|
166 namespace js { |
|
167 |
|
168 extern const char * const TypeStrings[]; |
|
169 |
|
170 /* |
|
171 * Atom tracing and garbage collection hooks. |
|
172 */ |
|
173 extern void |
|
174 MarkAtoms(JSTracer *trc); |
|
175 |
|
176 extern void |
|
177 MarkPermanentAtoms(JSTracer *trc); |
|
178 |
|
179 /* N.B. must correspond to boolean tagging behavior. */ |
|
180 enum InternBehavior |
|
181 { |
|
182 DoNotInternAtom = false, |
|
183 InternAtom = true |
|
184 }; |
|
185 |
|
186 extern JSAtom * |
|
187 Atomize(ExclusiveContext *cx, const char *bytes, size_t length, |
|
188 js::InternBehavior ib = js::DoNotInternAtom); |
|
189 |
|
190 extern JSAtom * |
|
191 AtomizeChars(ExclusiveContext *cx, const jschar *chars, size_t length, |
|
192 js::InternBehavior ib = js::DoNotInternAtom); |
|
193 |
|
194 extern JSAtom * |
|
195 AtomizeString(ExclusiveContext *cx, JSString *str, js::InternBehavior ib = js::DoNotInternAtom); |
|
196 |
|
197 template <AllowGC allowGC> |
|
198 extern JSAtom * |
|
199 ToAtom(ExclusiveContext *cx, typename MaybeRooted<Value, allowGC>::HandleType v); |
|
200 |
|
201 enum XDRMode { |
|
202 XDR_ENCODE, |
|
203 XDR_DECODE |
|
204 }; |
|
205 |
|
206 template <XDRMode mode> |
|
207 class XDRState; |
|
208 |
|
209 template<XDRMode mode> |
|
210 bool |
|
211 XDRAtom(XDRState<mode> *xdr, js::MutableHandleAtom atomp); |
|
212 |
|
213 } /* namespace js */ |
|
214 |
|
215 #endif /* jsatom_h */ |