Coverage Report

Created: 2025-06-16 06:50

/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
}