/rust/git/checkouts/mozjs-fa11ffc7d4f1cc2d/d90edd1/mozjs-sys/src/jsid.rs
Line | Count | Source (jump to first uncovered line) |
1 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
2 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
3 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
4 | | |
5 | | #![allow(non_snake_case)] |
6 | | |
7 | | use crate::jsapi::JS::Symbol; |
8 | | use crate::jsapi::{jsid, JSString}; |
9 | | use libc::c_void; |
10 | | |
11 | | #[deprecated] |
12 | | pub const JSID_VOID: jsid = VoidId(); |
13 | | |
14 | | const JSID_TYPE_MASK: usize = 0x7; |
15 | | |
16 | | #[repr(usize)] |
17 | | enum PropertyKeyTag { |
18 | | Int = 0x1, |
19 | | String = 0x0, |
20 | | Void = 0x2, |
21 | | Symbol = 0x4, |
22 | | } |
23 | | |
24 | | #[inline(always)] |
25 | 0 | const fn AsPropertyKey(bits: usize) -> jsid { |
26 | 0 | jsid { asBits_: bits } |
27 | 0 | } |
28 | | |
29 | | #[inline(always)] |
30 | 0 | pub const fn VoidId() -> jsid { |
31 | 0 | AsPropertyKey(PropertyKeyTag::Void as usize) |
32 | 0 | } |
33 | | |
34 | | #[inline(always)] |
35 | 0 | pub fn IntId(i: i32) -> jsid { |
36 | 0 | assert!(i >= 0); |
37 | 0 | AsPropertyKey((((i as u32) << 1) as usize) | (PropertyKeyTag::Int as usize)) |
38 | 0 | } |
39 | | |
40 | | #[inline(always)] |
41 | 0 | pub fn SymbolId(symbol: *mut Symbol) -> jsid { |
42 | 0 | assert!(!symbol.is_null()); |
43 | 0 | assert_eq!((symbol as usize) & JSID_TYPE_MASK, 0); |
44 | 0 | AsPropertyKey((symbol as usize) | (PropertyKeyTag::Symbol as usize)) |
45 | 0 | } |
46 | | |
47 | | impl jsid { |
48 | | #[inline(always)] |
49 | 0 | fn asBits(&self) -> usize { |
50 | 0 | self.asBits_ |
51 | 0 | } |
52 | | |
53 | | #[inline(always)] |
54 | 0 | pub fn is_void(&self) -> bool { |
55 | 0 | self.asBits() == (PropertyKeyTag::Void as usize) |
56 | 0 | } |
57 | | |
58 | | #[inline(always)] |
59 | 0 | pub fn is_int(&self) -> bool { |
60 | 0 | (self.asBits() & (PropertyKeyTag::Int as usize)) != 0 |
61 | 0 | } |
62 | | |
63 | | #[inline(always)] |
64 | 0 | pub fn is_string(&self) -> bool { |
65 | 0 | (self.asBits() & JSID_TYPE_MASK) == (PropertyKeyTag::String as usize) |
66 | 0 | } |
67 | | |
68 | | #[inline(always)] |
69 | 0 | pub fn is_symbol(&self) -> bool { |
70 | 0 | (self.asBits() & JSID_TYPE_MASK) == (PropertyKeyTag::Symbol as usize) |
71 | 0 | } |
72 | | |
73 | | #[inline(always)] |
74 | 0 | pub fn is_gcthing(&self) -> bool { |
75 | 0 | self.is_string() && self.is_symbol() |
76 | 0 | } |
77 | | |
78 | | #[inline(always)] |
79 | 0 | pub fn to_int(&self) -> i32 { |
80 | 0 | assert!(self.is_int()); |
81 | 0 | ((self.asBits() as u32) >> 1) as i32 |
82 | 0 | } |
83 | | |
84 | | #[inline(always)] |
85 | 0 | pub fn to_string(&self) -> *mut JSString { |
86 | 0 | assert!(self.is_string()); |
87 | 0 | (self.asBits() ^ (PropertyKeyTag::String as usize)) as *mut JSString |
88 | 0 | } |
89 | | |
90 | | #[inline(always)] |
91 | 0 | pub fn to_symbol(&self) -> *mut Symbol { |
92 | 0 | assert!(self.is_symbol()); |
93 | 0 | (self.asBits() ^ (PropertyKeyTag::Symbol as usize)) as *mut Symbol |
94 | 0 | } |
95 | | |
96 | | #[inline(always)] |
97 | 0 | pub fn to_gcthing(&self) -> *mut c_void { |
98 | 0 | assert!(self.is_gcthing()); |
99 | 0 | (self.asBits() ^ JSID_TYPE_MASK) as *mut c_void |
100 | 0 | } |
101 | | } |
102 | | |
103 | | #[test] |
104 | | fn test_representation() { |
105 | | let id = VoidId(); |
106 | | assert!(id.is_void()); |
107 | | |
108 | | let id = IntId(0); |
109 | | assert!(id.is_int()); |
110 | | assert_eq!(id.to_int(), 0); |
111 | | |
112 | | let id = IntId(i32::MAX); |
113 | | assert!(id.is_int()); |
114 | | assert_eq!(id.to_int(), i32::MAX); |
115 | | } |