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 vm_SharedImmutableStringsCache_inl_h
8 #define vm_SharedImmutableStringsCache_inl_h
9 
10 #include "vm/SharedImmutableStringsCache.h"
11 
12 namespace js {
13 
14 template <typename IntoOwnedChars>
15 MOZ_MUST_USE mozilla::Maybe<SharedImmutableString>
getOrCreate(const char * chars,size_t length,IntoOwnedChars intoOwnedChars)16 SharedImmutableStringsCache::getOrCreate(const char* chars, size_t length,
17                                          IntoOwnedChars intoOwnedChars) {
18   MOZ_ASSERT(inner_);
19   MOZ_ASSERT(chars);
20   Hasher::Lookup lookup(Hasher::hashLongString(chars, length), chars, length);
21 
22   auto locked = inner_->lock();
23   if (!locked->set.initialized() && !locked->set.init())
24     return mozilla::Nothing();
25 
26   auto entry = locked->set.lookupForAdd(lookup);
27   if (!entry) {
28     OwnedChars ownedChars(intoOwnedChars());
29     if (!ownedChars) return mozilla::Nothing();
30     MOZ_ASSERT(ownedChars.get() == chars ||
31                memcmp(ownedChars.get(), chars, length) == 0);
32     auto box = StringBox::Create(mozilla::Move(ownedChars), length);
33     if (!box || !locked->set.add(entry, mozilla::Move(box)))
34       return mozilla::Nothing();
35   }
36 
37   MOZ_ASSERT(entry && *entry);
38   return mozilla::Some(SharedImmutableString(locked, entry->get()));
39 }
40 
41 template <typename IntoOwnedTwoByteChars>
42 MOZ_MUST_USE mozilla::Maybe<SharedImmutableTwoByteString>
getOrCreate(const char16_t * chars,size_t length,IntoOwnedTwoByteChars intoOwnedTwoByteChars)43 SharedImmutableStringsCache::getOrCreate(
44     const char16_t* chars, size_t length,
45     IntoOwnedTwoByteChars intoOwnedTwoByteChars) {
46   MOZ_ASSERT(inner_);
47   MOZ_ASSERT(chars);
48   auto hash = Hasher::hashLongString(reinterpret_cast<const char*>(chars),
49                                      length * sizeof(char16_t));
50   Hasher::Lookup lookup(hash, chars, length);
51 
52   auto locked = inner_->lock();
53   if (!locked->set.initialized() && !locked->set.init())
54     return mozilla::Nothing();
55 
56   auto entry = locked->set.lookupForAdd(lookup);
57   if (!entry) {
58     OwnedTwoByteChars ownedTwoByteChars(intoOwnedTwoByteChars());
59     if (!ownedTwoByteChars) return mozilla::Nothing();
60     MOZ_ASSERT(
61         ownedTwoByteChars.get() == chars ||
62         memcmp(ownedTwoByteChars.get(), chars, length * sizeof(char16_t)) == 0);
63     OwnedChars ownedChars(reinterpret_cast<char*>(ownedTwoByteChars.release()));
64     auto box =
65         StringBox::Create(mozilla::Move(ownedChars), length * sizeof(char16_t));
66     if (!box || !locked->set.add(entry, mozilla::Move(box)))
67       return mozilla::Nothing();
68   }
69 
70   MOZ_ASSERT(entry && *entry);
71   return mozilla::Some(SharedImmutableTwoByteString(locked, entry->get()));
72 }
73 
74 }  // namespace js
75 
76 #endif  // vm_SharedImmutableStringsCache_inl_h
77