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 jsatominlines_h___
41 : #define jsatominlines_h___
42 :
43 : #include "jsatom.h"
44 : #include "jsnum.h"
45 : #include "jsobj.h"
46 : #include "jsstr.h"
47 :
48 : #include "mozilla/RangedPtr.h"
49 : #include "vm/String.h"
50 :
51 : inline JSAtom *
52 255026699 : js::AtomStateEntry::asPtr() const
53 : {
54 255026699 : JS_ASSERT(bits != 0);
55 255026699 : JSAtom *atom = reinterpret_cast<JSAtom *>(bits & NO_TAG_MASK);
56 255026699 : JSString::readBarrier(atom);
57 255026699 : return atom;
58 : }
59 :
60 : inline bool
61 23584860 : js_ValueToAtom(JSContext *cx, const js::Value &v, JSAtom **atomp)
62 : {
63 23584860 : if (!v.isString()) {
64 3363591 : JSString *str = js::ToStringSlow(cx, v);
65 3363591 : if (!str)
66 0 : return false;
67 6727182 : JS::Anchor<JSString *> anchor(str);
68 3363591 : *atomp = js_AtomizeString(cx, str);
69 3363591 : return !!*atomp;
70 : }
71 :
72 20221269 : JSString *str = v.toString();
73 20221269 : if (str->isAtom()) {
74 18903577 : *atomp = &str->asAtom();
75 18903577 : return true;
76 : }
77 :
78 1317692 : *atomp = js_AtomizeString(cx, str);
79 1317692 : return !!*atomp;
80 : }
81 :
82 : inline bool
83 13964951 : js_ValueToStringId(JSContext *cx, const js::Value &v, jsid *idp)
84 : {
85 : JSAtom *atom;
86 13964951 : if (js_ValueToAtom(cx, v, &atom)) {
87 13964951 : *idp = ATOM_TO_JSID(atom);
88 13964951 : return true;
89 : }
90 0 : return false;
91 : }
92 :
93 : inline bool
94 8566 : js_InternNonIntElementId(JSContext *cx, JSObject *obj, const js::Value &idval,
95 : jsid *idp)
96 : {
97 8566 : JS_ASSERT(!idval.isInt32() || !INT_FITS_IN_JSID(idval.toInt32()));
98 :
99 : #if JS_HAS_XML_SUPPORT
100 : extern bool js_InternNonIntElementIdSlow(JSContext *, JSObject *,
101 : const js::Value &, jsid *);
102 8566 : if (idval.isObject())
103 6 : return js_InternNonIntElementIdSlow(cx, obj, idval, idp);
104 : #endif
105 :
106 8560 : return js_ValueToStringId(cx, idval, idp);
107 : }
108 :
109 : inline bool
110 1520714 : js_InternNonIntElementId(JSContext *cx, JSObject *obj, const js::Value &idval,
111 : jsid *idp, js::Value *vp)
112 : {
113 1520714 : JS_ASSERT(!idval.isInt32() || !INT_FITS_IN_JSID(idval.toInt32()));
114 :
115 : #if JS_HAS_XML_SUPPORT
116 : extern bool js_InternNonIntElementIdSlow(JSContext *, JSObject *,
117 : const js::Value &,
118 : jsid *, js::Value *);
119 1520714 : if (idval.isObject())
120 3479 : return js_InternNonIntElementIdSlow(cx, obj, idval, idp, vp);
121 : #endif
122 :
123 : JSAtom *atom;
124 1517235 : if (js_ValueToAtom(cx, idval, &atom)) {
125 1517235 : *idp = ATOM_TO_JSID(atom);
126 1517235 : vp->setString(atom);
127 1517235 : return true;
128 : }
129 0 : return false;
130 : }
131 :
132 : inline bool
133 : js_Int32ToId(JSContext* cx, int32_t index, jsid* id)
134 : {
135 : if (INT_FITS_IN_JSID(index)) {
136 : *id = INT_TO_JSID(index);
137 : return true;
138 : }
139 :
140 : JSString* str = js_NumberToString(cx, index);
141 : if (!str)
142 : return false;
143 :
144 : return js_ValueToStringId(cx, js::StringValue(str), id);
145 : }
146 :
147 : namespace js {
148 :
149 : /*
150 : * Write out character representing |index| to the memory just before |end|.
151 : * Thus |*end| is not touched, but |end[-1]| and earlier are modified as
152 : * appropriate. There must be at least js::UINT32_CHAR_BUFFER_LENGTH elements
153 : * before |end| to avoid buffer underflow. The start of the characters written
154 : * is returned and is necessarily before |end|.
155 : */
156 : template <typename T>
157 : inline mozilla::RangedPtr<T>
158 43065053 : BackfillIndexInCharBuffer(uint32_t index, mozilla::RangedPtr<T> end)
159 : {
160 : #ifdef DEBUG
161 : /*
162 : * Assert that the buffer we're filling will hold as many characters as we
163 : * could write out, by dereferencing the index that would hold the most
164 : * significant digit.
165 : */
166 43065053 : (void) *(end - UINT32_CHAR_BUFFER_LENGTH);
167 : #endif
168 :
169 276448875 : do {
170 276448875 : uint32_t next = index / 10, digit = index % 10;
171 276448875 : *--end = '0' + digit;
172 276448875 : index = next;
173 : } while (index > 0);
174 :
175 43065053 : return end;
176 : }
177 :
178 : inline bool
179 34064401 : IndexToId(JSContext *cx, uint32_t index, jsid *idp)
180 : {
181 34064401 : if (index <= JSID_INT_MAX) {
182 34064168 : *idp = INT_TO_JSID(index);
183 34064168 : return true;
184 : }
185 :
186 : extern bool IndexToIdSlow(JSContext *cx, uint32_t index, jsid *idp);
187 233 : return IndexToIdSlow(cx, index, idp);
188 : }
189 :
190 : static JS_ALWAYS_INLINE JSFlatString *
191 56075160 : IdToString(JSContext *cx, jsid id)
192 : {
193 56075160 : if (JSID_IS_STRING(id))
194 14516165 : return JSID_TO_ATOM(id);
195 :
196 : JSString *str;
197 41558995 : if (JS_LIKELY(JSID_IS_INT(id)))
198 41558959 : str = js_IntToString(cx, JSID_TO_INT(id));
199 : else
200 36 : str = ToStringSlow(cx, IdToValue(id));
201 :
202 41558995 : if (!str)
203 9 : return NULL;
204 41558986 : return str->ensureFlat(cx);
205 : }
206 :
207 : inline
208 4231234 : AtomHasher::Lookup::Lookup(const JSAtom *atom)
209 4231234 : : chars(atom->chars()), length(atom->length()), atom(atom)
210 4231234 : {}
211 :
212 : inline bool
213 57808970 : AtomHasher::match(const AtomStateEntry &entry, const Lookup &lookup)
214 : {
215 57808970 : JSAtom *key = entry.asPtr();
216 57808970 : if (lookup.atom)
217 4231234 : return lookup.atom == key;
218 53577736 : if (key->length() != lookup.length)
219 9784 : return false;
220 53567952 : return PodEqual(key->chars(), lookup.chars, lookup.length);
221 : }
222 :
223 : } // namespace js
224 :
225 : #endif /* jsatominlines_h___ */
|