1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 /* Symbols. */
7 
8 #ifndef js_Symbol_h
9 #define js_Symbol_h
10 
11 #include "js/shadow/Symbol.h"  // JS::shadow::Symbol::WellKnownAPILimit
12 
13 #include <stddef.h>  // size_t
14 #include <stdint.h>  // uintptr_t, uint32_t
15 
16 #include "jstypes.h"  // JS_PUBLIC_API
17 
18 #include "js/TypeDecls.h"
19 
20 namespace JS {
21 
22 class JS_PUBLIC_API Symbol;
23 
24 /**
25  * Create a new Symbol with the given description. This function never returns
26  * a Symbol that is in the Runtime-wide symbol registry.
27  *
28  * If description is null, the new Symbol's [[Description]] attribute is
29  * undefined.
30  */
31 extern JS_PUBLIC_API Symbol* NewSymbol(JSContext* cx,
32                                        Handle<JSString*> description);
33 
34 /**
35  * Symbol.for as specified in ES6.
36  *
37  * Get a Symbol with the description 'key' from the Runtime-wide symbol
38  * registry. If there is not already a Symbol with that description in the
39  * registry, a new Symbol is created and registered. 'key' must not be null.
40  */
41 extern JS_PUBLIC_API Symbol* GetSymbolFor(JSContext* cx, Handle<JSString*> key);
42 
43 /**
44  * Get the [[Description]] attribute of the given symbol.
45  *
46  * This function is infallible. If it returns null, that means the symbol's
47  * [[Description]] is undefined.
48  */
49 extern JS_PUBLIC_API JSString* GetSymbolDescription(Handle<Symbol*> symbol);
50 
51 /* Well-known symbols. */
52 #define JS_FOR_EACH_WELL_KNOWN_SYMBOL(MACRO) \
53   MACRO(isConcatSpreadable)                  \
54   MACRO(iterator)                            \
55   MACRO(match)                               \
56   MACRO(replace)                             \
57   MACRO(search)                              \
58   MACRO(species)                             \
59   MACRO(hasInstance)                         \
60   MACRO(split)                               \
61   MACRO(toPrimitive)                         \
62   MACRO(toStringTag)                         \
63   MACRO(unscopables)                         \
64   MACRO(asyncIterator)                       \
65   MACRO(matchAll)
66 
67 enum class SymbolCode : uint32_t {
68 // There is one SymbolCode for each well-known symbol.
69 #define JS_DEFINE_SYMBOL_ENUM(name) name,
70   JS_FOR_EACH_WELL_KNOWN_SYMBOL(
71       JS_DEFINE_SYMBOL_ENUM)  // SymbolCode::iterator, etc.
72 #undef JS_DEFINE_SYMBOL_ENUM
73   Limit,
74   WellKnownAPILimit = JS::shadow::Symbol::WellKnownAPILimit,
75   PrivateNameSymbol = 0xfffffffd,  // created by the #PrivateName syntax.
76   InSymbolRegistry =
77       0xfffffffe,            // created by Symbol.for() or JS::GetSymbolFor()
78   UniqueSymbol = 0xffffffff  // created by Symbol() or JS::NewSymbol()
79 };
80 
81 /* For use in loops that iterate over the well-known symbols. */
82 const size_t WellKnownSymbolLimit = size_t(SymbolCode::Limit);
83 
84 /**
85  * Return the SymbolCode telling what sort of symbol `symbol` is.
86  *
87  * A symbol's SymbolCode never changes once it is created.
88  */
89 extern JS_PUBLIC_API SymbolCode GetSymbolCode(Handle<Symbol*> symbol);
90 
91 /**
92  * Get one of the well-known symbols defined by ES6. A single set of well-known
93  * symbols is shared by all compartments in a JSRuntime.
94  *
95  * `which` must be in the range [0, WellKnownSymbolLimit).
96  */
97 extern JS_PUBLIC_API Symbol* GetWellKnownSymbol(JSContext* cx,
98                                                 SymbolCode which);
99 
100 /**
101  * Return true if the given JSPropertySpec::name or JSFunctionSpec::name value
102  * is actually a symbol code and not a string. See JS_SYM_FN.
103  */
PropertySpecNameIsSymbol(uintptr_t name)104 inline bool PropertySpecNameIsSymbol(uintptr_t name) {
105   return name != 0 && name - 1 < WellKnownSymbolLimit;
106 }
107 
108 }  // namespace JS
109 
110 #endif /* js_Symbol_h */
111