Skip to main content

v8/
symbol.rs

1use crate::Local;
2use crate::String;
3use crate::Symbol;
4use crate::Value;
5use crate::isolate::RealIsolate;
6use crate::scope::PinScope;
7
8unsafe extern "C" {
9  fn v8__Symbol__New(
10    isolate: *mut RealIsolate,
11    description: *const String,
12  ) -> *const Symbol;
13  fn v8__Symbol__For(
14    isolate: *mut RealIsolate,
15    description: *const String,
16  ) -> *const Symbol;
17  fn v8__Symbol__ForApi(
18    isolate: *mut RealIsolate,
19    description: *const String,
20  ) -> *const Symbol;
21  fn v8__Symbol__Description(
22    this: *const Symbol,
23    isolate: *mut RealIsolate,
24  ) -> *const Value;
25}
26
27macro_rules! well_known {
28  ($name:ident, $binding:ident) => {
29    pub fn $name<'s>(scope: &PinScope<'s, '_, ()>) -> Local<'s, Symbol> {
30      unsafe extern "C" {
31        fn $binding(isolate: *mut RealIsolate) -> *const Symbol;
32      }
33      unsafe { scope.cast_local(|sd| $binding(sd.get_isolate_ptr())) }.unwrap()
34    }
35  };
36}
37
38impl Symbol {
39  /// Create a symbol. If description is not empty, it will be used as the
40  /// description.
41  #[inline(always)]
42  pub fn new<'s>(
43    scope: &PinScope<'s, '_, ()>,
44    description: Option<Local<String>>,
45  ) -> Local<'s, Symbol> {
46    unsafe {
47      scope.cast_local(|sd| {
48        v8__Symbol__New(
49          sd.get_isolate_ptr(),
50          description.map_or_else(std::ptr::null, |v| &*v),
51        )
52      })
53    }
54    .unwrap()
55  }
56
57  /// Access global symbol registry.
58  /// Note that symbols created this way are never collected, so
59  /// they should only be used for statically fixed properties.
60  /// Also, there is only one global description space for the descriptions used as
61  /// keys.
62  /// To minimize the potential for clashes, use qualified descriptions as keys.
63  /// Corresponds to v8::Symbol::For() in C++.
64  #[inline(always)]
65  pub fn for_key<'s>(
66    scope: &PinScope<'s, '_, ()>,
67    description: Local<String>,
68  ) -> Local<'s, Symbol> {
69    unsafe {
70      scope
71        .cast_local(|sd| v8__Symbol__For(sd.get_isolate_ptr(), &*description))
72    }
73    .unwrap()
74  }
75
76  /// Retrieve a global symbol. Similar to `for_key`, but using a separate
77  /// registry that is not accessible by (and cannot clash with) JavaScript code.
78  /// Corresponds to v8::Symbol::ForApi() in C++.
79  #[inline(always)]
80  pub fn for_api<'s>(
81    scope: &PinScope<'s, '_, ()>,
82    description: Local<String>,
83  ) -> Local<'s, Symbol> {
84    unsafe {
85      scope.cast_local(|sd| {
86        v8__Symbol__ForApi(sd.get_isolate_ptr(), &*description)
87      })
88    }
89    .unwrap()
90  }
91
92  /// Returns the description string of the symbol, or undefined if none.
93  #[inline(always)]
94  pub fn description<'s>(
95    &self,
96    scope: &PinScope<'s, '_, ()>,
97  ) -> Local<'s, Value> {
98    unsafe {
99      scope.cast_local(|sd| v8__Symbol__Description(self, sd.get_isolate_ptr()))
100    }
101    .unwrap()
102  }
103
104  well_known!(get_async_iterator, v8__Symbol__GetAsyncIterator);
105  well_known!(get_has_instance, v8__Symbol__GetHasInstance);
106  well_known!(get_is_concat_spreadable, v8__Symbol__GetIsConcatSpreadable);
107  well_known!(get_iterator, v8__Symbol__GetIterator);
108  well_known!(get_match, v8__Symbol__GetMatch);
109  well_known!(get_replace, v8__Symbol__GetReplace);
110  well_known!(get_search, v8__Symbol__GetSearch);
111  well_known!(get_split, v8__Symbol__GetSplit);
112  well_known!(get_to_primitive, v8__Symbol__GetToPrimitive);
113  well_known!(get_to_string_tag, v8__Symbol__GetToStringTag);
114  well_known!(get_unscopables, v8__Symbol__GetUnscopables);
115}