Skip to content

Commit 673b992

Browse files
authored
Added BigInt Support (#384)
* Added BigInt Value Support * Added BigInt Root Support * Added BigInt Functions To Bindings * Added Tracing for Heap<BigInt> and Heap<Symbol>
1 parent 635d233 commit 673b992

File tree

6 files changed

+100
-5
lines changed

6 files changed

+100
-5
lines changed

mozjs/src/jsgc.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@ impl RootKind for *mut JS::Symbol {
4646
}
4747
}
4848

49+
impl RootKind for *mut JS::BigInt {
50+
#[inline(always)]
51+
fn rootKind() -> JS::RootKind {
52+
JS::RootKind::BigInt
53+
}
54+
}
55+
4956
impl RootKind for *mut JSScript {
5057
#[inline(always)]
5158
fn rootKind() -> JS::RootKind {
@@ -132,6 +139,15 @@ impl GCMethods for *mut JS::Symbol {
132139
unsafe fn post_barrier(_: *mut *mut JS::Symbol, _: *mut JS::Symbol, _: *mut JS::Symbol) {}
133140
}
134141

142+
impl GCMethods for *mut JS::BigInt {
143+
unsafe fn initial() -> *mut JS::BigInt {
144+
ptr::null_mut()
145+
}
146+
unsafe fn post_barrier(v: *mut *mut JS::BigInt, prev: *mut JS::BigInt, next: *mut JS::BigInt) {
147+
JS::HeapBigIntWriteBarriers(v, prev, next);
148+
}
149+
}
150+
135151
impl GCMethods for *mut JSScript {
136152
unsafe fn initial() -> *mut JSScript {
137153
ptr::null_mut()

mozjs/src/jsglue.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#define _JSGLUE_INCLUDED
99

1010
#include "js/ArrayBuffer.h"
11+
#include "js/BigInt.h"
1112
#include "js/BuildId.h"
1213
#include "js/CompilationAndEvaluation.h"
1314
#include "js/ContextOptions.h"

mozjs/src/jsval.rs

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use jsapi::JSContext;
99
use jsapi::JSObject;
1010
use jsapi::JSString;
1111
use jsapi::JSValueType;
12+
use jsapi::JS::BigInt;
1213
use jsapi::JS::Symbol;
1314
use jsapi::JS::TraceKind;
1415
use jsapi::JS::Value;
@@ -36,6 +37,7 @@ enum ValueTag {
3637
UNDEFINED = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_UNDEFINED as u32),
3738
STRING = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_STRING as u32),
3839
SYMBOL = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_SYMBOL as u32),
40+
BIGINT = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_BIGINT as u32),
3941
BOOLEAN = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_BOOLEAN as u32),
4042
MAGIC = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_MAGIC as u32),
4143
NULL = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_NULL as u32),
@@ -51,6 +53,7 @@ enum ValueTag {
5153
UNDEFINED = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_UNDEFINED as u32),
5254
STRING = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_STRING as u32),
5355
SYMBOL = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_SYMBOL as u32),
56+
BIGINT = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_BIGINT as u32),
5457
BOOLEAN = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_BOOLEAN as u32),
5558
MAGIC = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_MAGIC as u32),
5659
NULL = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_NULL as u32),
@@ -66,6 +69,7 @@ enum ValueShiftedTag {
6669
UNDEFINED = (ValueTag::UNDEFINED as u64) << JSVAL_TAG_SHIFT,
6770
STRING = (ValueTag::STRING as u64) << JSVAL_TAG_SHIFT,
6871
SYMBOL = (ValueTag::SYMBOL as u64) << JSVAL_TAG_SHIFT,
72+
BIGINT = (ValueTag::BIGINT as u64) << JSVAL_TAG_SHIFT,
6973
BOOLEAN = (ValueTag::BOOLEAN as u64) << JSVAL_TAG_SHIFT,
7074
MAGIC = (ValueTag::MAGIC as u64) << JSVAL_TAG_SHIFT,
7175
NULL = (ValueTag::NULL as u64) << JSVAL_TAG_SHIFT,
@@ -191,6 +195,21 @@ pub fn SymbolValue(s: &Symbol) -> JSVal {
191195
BuildJSVal(ValueTag::SYMBOL, bits)
192196
}
193197

198+
#[cfg(target_pointer_width = "64")]
199+
#[inline(always)]
200+
pub fn BigIntValue(s: &BigInt) -> JSVal {
201+
let bits = s as *const BigInt as usize as u64;
202+
assert!((bits >> JSVAL_TAG_SHIFT) == 0);
203+
BuildJSVal(ValueTag::BIGINT, bits)
204+
}
205+
206+
#[cfg(target_pointer_width = "32")]
207+
#[inline(always)]
208+
pub fn BigIntValue(s: &BigInt) -> JSVal {
209+
let bits = s as *const BigInt as usize as u64;
210+
BuildJSVal(ValueTag::BIGINT, bits)
211+
}
212+
194213
#[inline(always)]
195214
pub fn PrivateValue(o: *const c_void) -> JSVal {
196215
let ptrBits = o as usize as u64;
@@ -363,6 +382,18 @@ impl JSVal {
363382
(self.asBits() >> 32) == ValueTag::SYMBOL as u64
364383
}
365384

385+
#[inline(always)]
386+
#[cfg(target_pointer_width = "64")]
387+
pub fn is_bigint(&self) -> bool {
388+
(self.asBits() >> JSVAL_TAG_SHIFT) == ValueTag::BIGINT as u64
389+
}
390+
391+
#[inline(always)]
392+
#[cfg(target_pointer_width = "32")]
393+
pub fn is_bigint(&self) -> bool {
394+
(self.asBits() >> 32) == ValueTag::BIGINT as u64
395+
}
396+
366397
#[inline(always)]
367398
#[cfg(target_pointer_width = "64")]
368399
pub fn is_gcthing(&self) -> bool {
@@ -459,6 +490,14 @@ impl JSVal {
459490
ptrBits as usize as *mut Symbol
460491
}
461492

493+
#[inline(always)]
494+
pub fn to_bigint(&self) -> *mut BigInt {
495+
assert!(self.is_bigint());
496+
let ptrBits = self.asBits() & JSVAL_PAYLOAD_MASK;
497+
assert!((ptrBits & 0x7) == 0);
498+
ptrBits as usize as *mut BigInt
499+
}
500+
462501
#[inline(always)]
463502
pub fn to_private(&self) -> *const c_void {
464503
assert!(self.is_double());
@@ -496,8 +535,10 @@ impl JSVal {
496535
TraceKind::Object
497536
} else if self.is_string() {
498537
TraceKind::String
499-
} else {
538+
} else if self.is_symbol() {
500539
TraceKind::Symbol
540+
} else {
541+
TraceKind::BigInt
501542
}
502543
}
503544
}

rust-mozjs/src/gc/trace.rs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
use c_str;
22
use glue::{
3-
CallFunctionTracer, CallIdTracer, CallObjectTracer, CallScriptTracer, CallStringTracer,
4-
CallValueTracer,
3+
CallBigIntTracer, CallFunctionTracer, CallIdTracer, CallObjectTracer, CallScriptTracer, CallStringTracer,
4+
CallSymbolTracer, CallValueTracer,
55
};
6-
use jsapi::{jsid, JSFunction, JSObject, JSScript, JSString, JSTracer, Value};
7-
use mozjs_sys::jsapi::JS::JobQueue;
6+
use jsapi::{BigInt, JobQueue, jsid, JSFunction, JSObject, JSScript, JSString, JSTracer, Symbol, Value};
87
use mozjs_sys::jsgc::Heap;
98
use std::borrow::Cow;
109
use std::cell::{Cell, RefCell, UnsafeCell};
@@ -61,6 +60,24 @@ unsafe impl Traceable for Heap<*mut JSObject> {
6160
}
6261
}
6362

63+
unsafe impl Traceable for Heap<*mut Symbol> {
64+
unsafe fn trace(&self, trc: *mut JSTracer) {
65+
if self.get().is_null() {
66+
return;
67+
}
68+
CallSymbolTracer(trc, self as *const _ as *mut Self, c_str!("symbol"));
69+
}
70+
}
71+
72+
unsafe impl Traceable for Heap<*mut BigInt> {
73+
unsafe fn trace(&self, trc: *mut JSTracer) {
74+
if self.get().is_null() {
75+
return;
76+
}
77+
CallBigIntTracer(trc, self as *const _ as *mut Self, c_str!("bigint"));
78+
}
79+
}
80+
6481
unsafe impl Traceable for Heap<*mut JSScript> {
6582
#[inline]
6683
unsafe fn trace(&self, trc: *mut JSTracer) {

rust-mozjs/src/glue.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,16 @@ extern "C" {
472472
strp: *mut Heap<*mut JSString>,
473473
name: *const c_char,
474474
);
475+
pub fn CallSymbolTracer(
476+
trc: *mut JSTracer,
477+
bip: *mut Heap<*mut Symbol>,
478+
name: *const c_char,
479+
);
480+
pub fn CallBigIntTracer(
481+
trc: *mut JSTracer,
482+
bip: *mut Heap<*mut BigInt>,
483+
name: *const c_char,
484+
);
475485
pub fn CallScriptTracer(
476486
trc: *mut JSTracer,
477487
scriptp: *mut Heap<*mut JSScript>,

rust-mozjs/src/jsglue.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -890,6 +890,16 @@ void CallStringTracer(JSTracer* trc, JS::Heap<JSString*>* strp,
890890
JS::TraceEdge(trc, strp, name);
891891
}
892892

893+
void CallSymbolTracer(JSTracer* trc, JS::Heap<JS::Symbol*>* bip,
894+
const char* name) {
895+
JS::TraceEdge(trc, bip, name);
896+
}
897+
898+
void CallBigIntTracer(JSTracer* trc, JS::Heap<JS::BigInt*>* bip,
899+
const char* name) {
900+
JS::TraceEdge(trc, bip, name);
901+
}
902+
893903
void CallScriptTracer(JSTracer* trc, JS::Heap<JSScript*>* scriptp,
894904
const char* name) {
895905
JS::TraceEdge(trc, scriptp, name);

0 commit comments

Comments
 (0)