bug 1366287 - Part 1.2: Add a BigInt type to the Rust bindings. r=Ms2ger

This commit is contained in:
Robin Templeton 2018-05-11 19:09:38 -07:00
Родитель 906544d813
Коммит 80fba2c27a
8 изменённых файлов: 79 добавлений и 6 удалений

Просмотреть файл

@ -39,6 +39,7 @@ doctest = false
debugmozjs = ['mozjs_sys/debugmozjs']
promises = ['mozjs_sys/promises']
nonzero = []
bigint = ['mozjs_sys/bigint']
[dependencies.mozjs_sys]
path = "../src"

Просмотреть файл

@ -73,6 +73,10 @@ fn build_jsapi_bindings() {
.clang_arg("-DJS_DEBUG");
}
if cfg!(feature = "bigint") {
builder = builder.clang_arg("-DENABLE_BIGINT");
}
let include_dir = get_mozjs_include_dir();
let include_dir = include_dir.to_str()
.expect("Path to mozjs include dir should be utf-8");
@ -99,6 +103,10 @@ fn build_jsapi_bindings() {
builder = builder.whitelist_function(func);
}
if cfg!(feature = "bigint") {
builder = builder.whitelist_type("JS::BigInt");
}
for ty in OPAQUE_TYPES {
builder = builder.opaque_type(ty);
}

Просмотреть файл

@ -25,6 +25,8 @@ enum ValueTag {
UNDEFINED = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_UNDEFINED as u32),
STRING = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_STRING as u32),
SYMBOL = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_SYMBOL as u32),
#[cfg(feature = "bigint")]
BIGINT = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_BIGINT as u32),
BOOLEAN = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_BOOLEAN as u32),
MAGIC = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_MAGIC as u32),
NULL = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_NULL as u32),
@ -41,6 +43,8 @@ enum ValueTag {
UNDEFINED = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_UNDEFINED as u32),
STRING = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_STRING as u32),
SYMBOL = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_SYMBOL as u32),
#[cfg(feature = "bigint")]
BIGINT = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_BIGINT as u32),
BOOLEAN = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_BOOLEAN as u32),
MAGIC = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_MAGIC as u32),
NULL = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_NULL as u32),
@ -57,6 +61,8 @@ enum ValueShiftedTag {
UNDEFINED = ((ValueTag::UNDEFINED as u64) << JSVAL_TAG_SHIFT),
STRING = ((ValueTag::STRING as u64) << JSVAL_TAG_SHIFT),
SYMBOL = ((ValueTag::SYMBOL as u64) << JSVAL_TAG_SHIFT),
#[cfg(feature = "bigint")]
BIGINT = ((ValueTag::BIGINT as u64) << JSVAL_TAG_SHIFT),
BOOLEAN = ((ValueTag::BOOLEAN as u64) << JSVAL_TAG_SHIFT),
MAGIC = ((ValueTag::MAGIC as u64) << JSVAL_TAG_SHIFT),
NULL = ((ValueTag::NULL as u64) << JSVAL_TAG_SHIFT),
@ -187,6 +193,23 @@ pub fn PrivateValue(o: *const c_void) -> JS::Value {
BuildJSVal(ValueTag::PRIVATE, ptrBits)
}
#[inline(always)]
#[cfg(feature = "bigint")]
#[cfg(target_pointer_width = "64")]
pub fn BigIntValue(b: &JS::BigInt) -> JS::Value {
let bits = b as *const JS::BigInt as usize as u64;
assert!((bits >> JSVAL_TAG_SHIFT) == 0);
BuildJSVal(ValueTag::BIGINT, bits)
}
#[inline(always)]
#[cfg(target_pointer_width = "32")]
#[inline(always)]
pub fn BigIntValue(s: &JS::BigInt) -> JS::Value {
let bits = s as *const JS::BigInt as usize as u64;
BuildJSVal(ValueTag::BIGINT, bits)
}
impl JS::Value {
#[inline(always)]
unsafe fn asBits(&self) -> u64 {
@ -363,6 +386,24 @@ impl JS::Value {
}
}
#[inline(always)]
#[cfg(feature = "bigint")]
#[cfg(target_pointer_width = "64")]
pub fn is_bigint(&self) -> bool {
unsafe {
(self.asBits() >> JSVAL_TAG_SHIFT) == ValueTag::BIGINT as u64
}
}
#[inline(always)]
#[cfg(feature = "bigint")]
#[cfg(target_pointer_width = "32")]
pub fn is_bigint(&self) -> bool {
unsafe {
(self.asBits() >> 32) == ValueTag::BIGINT as u64
}
}
#[inline(always)]
#[cfg(target_pointer_width = "64")]
pub fn to_boolean(&self) -> bool {

Просмотреть файл

@ -306,6 +306,12 @@ impl RootKind for *mut JS::Symbol {
fn rootKind() -> JS::RootKind { JS::RootKind::Symbol }
}
#[cfg(feature = "bigint")]
impl RootKind for *mut JS::BigInt {
#[inline(always)]
fn rootKind() -> JS::RootKind { JS::RootKind::BigInt }
}
impl RootKind for *mut JSScript {
#[inline(always)]
fn rootKind() -> JS::RootKind { JS::RootKind::Script }

Просмотреть файл

@ -8,6 +8,7 @@ build = "build.rs"
[features]
debugmozjs = []
promises = []
bigint = []
[lib]
name = "mozjs_sys"

Просмотреть файл

@ -16,11 +16,9 @@ fn main() {
env::set_var("MAKEFLAGS", format!("-j{}", num_cpus::get()));
env::set_current_dir(&js_src).unwrap();
let variant = if cfg!(feature = "debugmozjs") {
"plaindebug"
} else {
"plain"
};
let variant = format!("{}{}",
if cfg!(feature = "bigint") { "bigint" } else { "plain" },
if cfg!(feature = "debugmozjs") { "debug" } else { "" });
let python = env::var("PYTHON").unwrap_or("python2.7".into());
let mut cmd = Command::new(&python);
@ -36,7 +34,7 @@ fn main() {
// already exists but wasn't created by autospider.
"--dep",
"--objdir", &out_dir,
variant])
&variant])
.env("SOURCE", &js_src)
.env("PWD", &js_src)
.stdout(Stdio::inherit())
@ -54,6 +52,10 @@ fn main() {
println!("cargo:rustc-link-search=native={}/dist/bin", out_dir);
println!("cargo:rustc-link-lib=nspr4");
if cfg!(feature = "bigint") {
println!("cargo:rustc-link-lib=gmp");
}
if target.contains("windows") {
println!("cargo:rustc-link-lib=winmm");
if target.contains("gnu") {

Просмотреть файл

@ -0,0 +1,7 @@
{
"configure-args": "--enable-bigint",
"optimize": true,
"env": {
"JSTESTS_EXTRA_ARGS": "--jitflags=all"
}
}

Просмотреть файл

@ -0,0 +1,7 @@
{
"configure-args": "--enable-bigint",
"debug": true,
"env": {
"JSTESTS_EXTRA_ARGS": "--jitflags=debug"
}
}