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