mirror of
https://github.com/denoland/rusty_v8.git
synced 2025-03-08 20:16:41 -05:00
add Symbol, Private, BigInt (#466)
This commit is contained in:
parent
6b90cbe499
commit
e5f56e218c
6 changed files with 477 additions and 2 deletions
135
src/bigint.rs
Normal file
135
src/bigint.rs
Normal file
|
@ -0,0 +1,135 @@
|
|||
use crate::support::int;
|
||||
use crate::BigInt;
|
||||
use crate::Context;
|
||||
use crate::HandleScope;
|
||||
use crate::Isolate;
|
||||
use crate::Local;
|
||||
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
extern "C" {
|
||||
fn v8__BigInt__New(isolate: *mut Isolate, value: i64) -> *const BigInt;
|
||||
fn v8__BigInt__NewFromUnsigned(
|
||||
isolate: *mut Isolate,
|
||||
value: u64,
|
||||
) -> *const BigInt;
|
||||
fn v8__BigInt__NewFromWords(
|
||||
context: *const Context,
|
||||
sign_bit: int,
|
||||
word_count: int,
|
||||
words: *const u64,
|
||||
) -> *const BigInt;
|
||||
fn v8__BigInt__Uint64Value(this: *const BigInt, lossless: *mut bool) -> u64;
|
||||
fn v8__BigInt__Int64Value(this: *const BigInt, lossless: *mut bool) -> i64;
|
||||
fn v8__BigInt__WordCount(this: *const BigInt) -> int;
|
||||
fn v8__BigInt__ToWordsArray(
|
||||
this: *const BigInt,
|
||||
sign_bit: *mut int,
|
||||
word_count: *mut int,
|
||||
words: *mut u64,
|
||||
);
|
||||
}
|
||||
|
||||
impl BigInt {
|
||||
pub fn new_from_i64<'s>(
|
||||
scope: &mut HandleScope<'s>,
|
||||
value: i64,
|
||||
) -> Local<'s, BigInt> {
|
||||
unsafe {
|
||||
scope.cast_local(|sd| v8__BigInt__New(sd.get_isolate_ptr(), value))
|
||||
}
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub fn new_from_u64<'s>(
|
||||
scope: &mut HandleScope<'s>,
|
||||
value: u64,
|
||||
) -> Local<'s, BigInt> {
|
||||
unsafe {
|
||||
scope.cast_local(|sd| {
|
||||
v8__BigInt__NewFromUnsigned(sd.get_isolate_ptr(), value)
|
||||
})
|
||||
}
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Creates a new BigInt object using a specified sign bit and a
|
||||
/// specified list of digits/words.
|
||||
/// The resulting number is calculated as:
|
||||
///
|
||||
/// (-1)^sign_bit * (words[0] * (2^64)^0 + words[1] * (2^64)^1 + ...)
|
||||
pub fn new_from_words<'s>(
|
||||
scope: &mut HandleScope<'s>,
|
||||
sign_bit: bool,
|
||||
words: &[u64],
|
||||
) -> Option<Local<'s, BigInt>> {
|
||||
unsafe {
|
||||
scope.cast_local(|sd| {
|
||||
v8__BigInt__NewFromWords(
|
||||
sd.get_current_context(),
|
||||
sign_bit as int,
|
||||
words.len() as int,
|
||||
words.as_ptr(),
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the value of this BigInt as an unsigned 64-bit integer, and a
|
||||
/// `bool` indicating whether the return value was truncated was truncated or
|
||||
/// wrapped around. In particular, it will be `false` if this BigInt is
|
||||
/// negative.
|
||||
pub fn u64_value(&self) -> (u64, bool) {
|
||||
let mut lossless = MaybeUninit::uninit();
|
||||
let v = unsafe { v8__BigInt__Uint64Value(&*self, lossless.as_mut_ptr()) };
|
||||
let lossless = unsafe { lossless.assume_init() };
|
||||
(v, lossless)
|
||||
}
|
||||
|
||||
/// Returns the value of this BigInt as a signed 64-bit integer, and a `bool`
|
||||
/// indicating whether this BigInt was truncated or not.
|
||||
pub fn i64_value(&self) -> (i64, bool) {
|
||||
let mut lossless = MaybeUninit::uninit();
|
||||
let v = unsafe { v8__BigInt__Int64Value(&*self, lossless.as_mut_ptr()) };
|
||||
let lossless = unsafe { lossless.assume_init() };
|
||||
(v, lossless)
|
||||
}
|
||||
|
||||
/// Returns the number of 64-bit words needed to store the result of
|
||||
/// `to_words_array`.
|
||||
pub fn word_count(&self) -> usize {
|
||||
unsafe { v8__BigInt__WordCount(&*self) as usize }
|
||||
}
|
||||
|
||||
/// Converts this BigInt to a (sign_bit, words) pair. `sign_bit` will be true
|
||||
/// if this BigInt is negative. If `words` has too few elements, the result will
|
||||
/// be truncated to fit.
|
||||
pub fn to_words_array<'a>(
|
||||
&self,
|
||||
words: &'a mut [u64],
|
||||
) -> (bool, &'a mut [u64]) {
|
||||
let mut sign_bit = MaybeUninit::uninit();
|
||||
let mut word_count = words.len() as int;
|
||||
unsafe {
|
||||
v8__BigInt__ToWordsArray(
|
||||
&*self,
|
||||
sign_bit.as_mut_ptr(),
|
||||
&mut word_count,
|
||||
words.as_mut_ptr(),
|
||||
)
|
||||
}
|
||||
|
||||
let sign_bit = unsafe { sign_bit.assume_init() };
|
||||
debug_assert!(sign_bit == 0 || sign_bit == 1);
|
||||
let word_count = word_count as usize;
|
||||
|
||||
(
|
||||
sign_bit == 1,
|
||||
if word_count < words.len() {
|
||||
&mut words[..word_count]
|
||||
} else {
|
||||
words
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
|
@ -717,6 +717,57 @@ int v8__String__WriteUtf8(const v8::String& self, v8::Isolate* isolate,
|
|||
return self.WriteUtf8(isolate, buffer, length, nchars_ref, options);
|
||||
}
|
||||
|
||||
const v8::Symbol* v8__Symbol__New(v8::Isolate* isolate,
|
||||
const v8::String* description) {
|
||||
return local_to_ptr(v8::Symbol::New(isolate, ptr_to_local(description)));
|
||||
}
|
||||
|
||||
const v8::Symbol* v8__Symbol__For(v8::Isolate* isolate,
|
||||
const v8::String* description) {
|
||||
return local_to_ptr(v8::Symbol::For(isolate, ptr_to_local(description)));
|
||||
}
|
||||
|
||||
const v8::Symbol* v8__Symbol__ForApi(v8::Isolate* isolate,
|
||||
const v8::String* description) {
|
||||
return local_to_ptr(v8::Symbol::ForApi(isolate, ptr_to_local(description)));
|
||||
}
|
||||
|
||||
#define V(NAME) \
|
||||
const v8::Symbol* v8__Symbol__Get##NAME(v8::Isolate* isolate) { \
|
||||
return local_to_ptr(v8::Symbol::Get##NAME(isolate)); \
|
||||
}
|
||||
|
||||
V(AsyncIterator)
|
||||
V(HasInstance)
|
||||
V(IsConcatSpreadable)
|
||||
V(Iterator)
|
||||
V(Match)
|
||||
V(Replace)
|
||||
V(Search)
|
||||
V(Split)
|
||||
V(ToPrimitive)
|
||||
V(ToStringTag)
|
||||
V(Unscopables)
|
||||
#undef V
|
||||
|
||||
const v8::Value* v8__Symbol__Description(const v8::Symbol& self) {
|
||||
return local_to_ptr(ptr_to_local(&self)->Description());
|
||||
}
|
||||
|
||||
const v8::Private* v8__Private__New(v8::Isolate* isolate,
|
||||
const v8::String* name) {
|
||||
return local_to_ptr(v8::Private::New(isolate, ptr_to_local(name)));
|
||||
}
|
||||
|
||||
const v8::Private* v8__Private__ForApi(v8::Isolate* isolate,
|
||||
const v8::String* name) {
|
||||
return local_to_ptr(v8::Private::ForApi(isolate, ptr_to_local(name)));
|
||||
}
|
||||
|
||||
const v8::Value* v8__Private__Name(const v8::Private& self) {
|
||||
return local_to_ptr(ptr_to_local(&self)->Name());
|
||||
}
|
||||
|
||||
void v8__Template__Set(const v8::Template& self, const v8::Name& key,
|
||||
const v8::Data& value, v8::PropertyAttribute attr) {
|
||||
ptr_to_local(&self)->Set(ptr_to_local(&key), ptr_to_local(&value), attr);
|
||||
|
@ -948,6 +999,39 @@ const v8::Integer* v8__Integer__NewFromUnsigned(v8::Isolate* isolate,
|
|||
|
||||
int64_t v8__Integer__Value(const v8::Integer& self) { return self.Value(); }
|
||||
|
||||
const v8::BigInt* v8__BigInt__New(v8::Isolate* isolate, int64_t value) {
|
||||
return local_to_ptr(v8::BigInt::New(isolate, value));
|
||||
}
|
||||
|
||||
const v8::BigInt* v8__BigInt__NewFromUnsigned(v8::Isolate* isolate,
|
||||
uint64_t value) {
|
||||
return local_to_ptr(v8::BigInt::NewFromUnsigned(isolate, value));
|
||||
}
|
||||
|
||||
const v8::BigInt* v8__BigInt__NewFromWords(const v8::Context& context,
|
||||
int sign_bit, int word_count,
|
||||
const uint64_t* words) {
|
||||
return maybe_local_to_ptr(v8::BigInt::NewFromWords(
|
||||
ptr_to_local(&context), sign_bit, word_count, words));
|
||||
}
|
||||
|
||||
uint64_t v8__BigInt__Uint64Value(const v8::BigInt& self, bool* lossless) {
|
||||
return ptr_to_local(&self)->Uint64Value(lossless);
|
||||
}
|
||||
|
||||
int64_t v8__BigInt__Int64Value(const v8::BigInt& self, bool* lossless) {
|
||||
return ptr_to_local(&self)->Int64Value(lossless);
|
||||
}
|
||||
|
||||
int v8__BigInt__WordCount(const v8::BigInt& self) {
|
||||
return ptr_to_local(&self)->WordCount();
|
||||
}
|
||||
|
||||
void v8__BigInt__ToWordsArray(const v8::BigInt& self, int* sign_bit,
|
||||
int* word_count, uint64_t* words) {
|
||||
ptr_to_local(&self)->ToWordsArray(sign_bit, word_count, words);
|
||||
}
|
||||
|
||||
const v8::ArrayBuffer* v8__ArrayBufferView__Buffer(
|
||||
const v8::ArrayBufferView& self) {
|
||||
return local_to_ptr(ptr_to_local(&self)->Buffer());
|
||||
|
|
|
@ -35,6 +35,7 @@ extern crate libc;
|
|||
|
||||
mod array_buffer;
|
||||
mod array_buffer_view;
|
||||
mod bigint;
|
||||
mod context;
|
||||
mod data;
|
||||
mod date;
|
||||
|
@ -52,6 +53,7 @@ mod object;
|
|||
mod platform;
|
||||
mod primitive_array;
|
||||
mod primitives;
|
||||
mod private;
|
||||
mod promise;
|
||||
mod property_attribute;
|
||||
mod proxy;
|
||||
|
@ -62,6 +64,7 @@ mod shared_array_buffer;
|
|||
mod snapshot;
|
||||
mod string;
|
||||
mod support;
|
||||
mod symbol;
|
||||
mod template;
|
||||
mod uint8_array;
|
||||
mod value;
|
||||
|
@ -75,6 +78,7 @@ pub mod script_compiler;
|
|||
pub mod V8;
|
||||
|
||||
pub use array_buffer::*;
|
||||
pub use bigint::*;
|
||||
pub use data::*;
|
||||
pub use exception::*;
|
||||
pub use external_references::ExternalReference;
|
||||
|
@ -103,6 +107,7 @@ pub use platform::Task;
|
|||
pub use platform::TaskBase;
|
||||
pub use platform::TaskImpl;
|
||||
pub use primitives::*;
|
||||
pub use private::*;
|
||||
pub use promise::{PromiseRejectEvent, PromiseRejectMessage, PromiseState};
|
||||
pub use property_attribute::*;
|
||||
pub use proxy::*;
|
||||
|
@ -120,6 +125,7 @@ pub use support::SharedPtr;
|
|||
pub use support::SharedRef;
|
||||
pub use support::UniquePtr;
|
||||
pub use support::UniqueRef;
|
||||
pub use symbol::*;
|
||||
pub use template::*;
|
||||
|
||||
// TODO(piscisaureus): Ideally this trait would not be exported.
|
||||
|
|
63
src/private.rs
Normal file
63
src/private.rs
Normal file
|
@ -0,0 +1,63 @@
|
|||
use crate::HandleScope;
|
||||
use crate::Isolate;
|
||||
use crate::Local;
|
||||
use crate::Private;
|
||||
use crate::String;
|
||||
use crate::Value;
|
||||
|
||||
extern "C" {
|
||||
fn v8__Private__New(
|
||||
isolate: *mut Isolate,
|
||||
name: *const String,
|
||||
) -> *const Private;
|
||||
fn v8__Private__ForApi(
|
||||
isolate: *mut Isolate,
|
||||
name: *const String,
|
||||
) -> *const Private;
|
||||
fn v8__Private__Name(this: *const Private) -> *const Value;
|
||||
}
|
||||
|
||||
impl Private {
|
||||
/// Create a private symbol. If name is not empty, it will be the description.
|
||||
pub fn new<'s>(
|
||||
scope: &mut HandleScope<'s>,
|
||||
name: Option<Local<String>>,
|
||||
) -> Local<'s, Private> {
|
||||
unsafe {
|
||||
scope.cast_local(|sd| {
|
||||
v8__Private__New(
|
||||
sd.get_isolate_ptr(),
|
||||
name.map_or_else(std::ptr::null, |v| &*v),
|
||||
)
|
||||
})
|
||||
}
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Retrieve a global private symbol. If a symbol with this name has not
|
||||
/// been retrieved in the same isolate before, it is created.
|
||||
/// Note that private symbols created this way are never collected, so
|
||||
/// they should only be used for statically fixed properties.
|
||||
/// Also, there is only one global name space for the names used as keys.
|
||||
/// To minimize the potential for clashes, use qualified names as keys,
|
||||
/// e.g., "Class#property".
|
||||
pub fn for_api<'s>(
|
||||
scope: &mut HandleScope<'s>,
|
||||
name: Option<Local<String>>,
|
||||
) -> Local<'s, Private> {
|
||||
unsafe {
|
||||
scope.cast_local(|sd| {
|
||||
v8__Private__ForApi(
|
||||
sd.get_isolate_ptr(),
|
||||
name.map_or_else(std::ptr::null, |v| &*v),
|
||||
)
|
||||
})
|
||||
}
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Returns the print name string of the private symbol, or undefined if none.
|
||||
pub fn name<'s>(&self, scope: &mut HandleScope<'s>) -> Local<'s, Value> {
|
||||
unsafe { scope.cast_local(|_| v8__Private__Name(&*self)) }.unwrap()
|
||||
}
|
||||
}
|
87
src/symbol.rs
Normal file
87
src/symbol.rs
Normal file
|
@ -0,0 +1,87 @@
|
|||
use crate::HandleScope;
|
||||
use crate::Isolate;
|
||||
use crate::Local;
|
||||
use crate::String;
|
||||
use crate::Symbol;
|
||||
use crate::Value;
|
||||
|
||||
extern "C" {
|
||||
fn v8__Symbol__New(
|
||||
isolate: *mut Isolate,
|
||||
description: *const String,
|
||||
) -> *const Symbol;
|
||||
fn v8__Symbol__ForApi(
|
||||
isolate: *mut Isolate,
|
||||
description: *const String,
|
||||
) -> *const Symbol;
|
||||
fn v8__Symbol__Description(this: *const Symbol) -> *const Value;
|
||||
}
|
||||
|
||||
macro_rules! well_known {
|
||||
($name:ident, $binding:ident) => {
|
||||
pub fn $name<'s>(scope: &mut HandleScope<'s>) -> Local<'s, Symbol> {
|
||||
extern "C" {
|
||||
fn $binding(isolate: *mut Isolate) -> *const Symbol;
|
||||
}
|
||||
unsafe { scope.cast_local(|sd| $binding(sd.get_isolate_ptr())) }.unwrap()
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl Symbol {
|
||||
/// Create a symbol. If description is not empty, it will be used as the
|
||||
/// description.
|
||||
pub fn new<'s>(
|
||||
scope: &mut HandleScope<'s>,
|
||||
description: Option<Local<String>>,
|
||||
) -> Local<'s, Symbol> {
|
||||
unsafe {
|
||||
scope.cast_local(|sd| {
|
||||
v8__Symbol__New(
|
||||
sd.get_isolate_ptr(),
|
||||
description.map_or_else(std::ptr::null, |v| &*v),
|
||||
)
|
||||
})
|
||||
}
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Access global symbol registry.
|
||||
/// Note that symbols created this way are never collected, so
|
||||
/// they should only be used for statically fixed properties.
|
||||
/// Also, there is only one global description space for the descriptions used as
|
||||
/// keys.
|
||||
/// To minimize the potential for clashes, use qualified descriptions as keys.
|
||||
/// Corresponds to v8::Symbol::For() in C++.
|
||||
pub fn for_global<'s>(
|
||||
scope: &mut HandleScope<'s>,
|
||||
description: Local<String>,
|
||||
) -> Local<'s, Symbol> {
|
||||
unsafe {
|
||||
scope.cast_local(|sd| {
|
||||
v8__Symbol__ForApi(sd.get_isolate_ptr(), &*description)
|
||||
})
|
||||
}
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Returns the description string of the symbol, or undefined if none.
|
||||
pub fn description<'s>(
|
||||
&self,
|
||||
scope: &mut HandleScope<'s>,
|
||||
) -> Local<'s, Value> {
|
||||
unsafe { scope.cast_local(|_| v8__Symbol__Description(&*self)) }.unwrap()
|
||||
}
|
||||
|
||||
well_known!(get_async_iterator, v8__Symbol__GetAsyncIterator);
|
||||
well_known!(get_has_instance, v8__Symbol__GetHasInstance);
|
||||
well_known!(get_is_concat_spreadable, v8__Symbol__GetIsConcatSpreadable);
|
||||
well_known!(get_iterator, v8__Symbol__GetIterator);
|
||||
well_known!(get_match, v8__Symbol__GetMatch);
|
||||
well_known!(get_replace, v8__Symbol__GetReplace);
|
||||
well_known!(get_search, v8__Symbol__GetSearch);
|
||||
well_known!(get_split, v8__Symbol__GetSplit);
|
||||
well_known!(get_to_primitive, v8__Symbol__GetToPrimitive);
|
||||
well_known!(get_to_string_tag, v8__Symbol__GetToStringTag);
|
||||
well_known!(get_unscopables, v8__Symbol__GetUnscopables);
|
||||
}
|
|
@ -2810,16 +2810,22 @@ fn try_from_data() {
|
|||
v8::Local::<v8::ObjectTemplate>::try_from(d).unwrap() == object_template
|
||||
);
|
||||
|
||||
// There is currently no way to construct instances of `v8::Private`,
|
||||
// therefore we don't have a test where `is_private()` succeeds.
|
||||
let p: v8::Local<v8::Data> = v8::Private::new(scope, None).into();
|
||||
assert!(!p.is_function_template());
|
||||
assert!(!p.is_module());
|
||||
assert!(!p.is_object_template());
|
||||
assert!(p.is_private());
|
||||
assert!(!p.is_value());
|
||||
|
||||
let values: &[v8::Local<v8::Value>] = &[
|
||||
v8::null(scope).into(),
|
||||
v8::undefined(scope).into(),
|
||||
v8::BigInt::new_from_u64(scope, 1337).into(),
|
||||
v8::Boolean::new(scope, true).into(),
|
||||
v8::Function::new(scope, function_callback).unwrap().into(),
|
||||
v8::Number::new(scope, 42.0).into(),
|
||||
v8::Object::new(scope).into(),
|
||||
v8::Symbol::new(scope, None).into(),
|
||||
v8::String::new(scope, "hello").unwrap().into(),
|
||||
];
|
||||
for &v in values {
|
||||
|
@ -3644,3 +3650,97 @@ fn date() {
|
|||
assert_eq!(date.value_of(), 3.0);
|
||||
assert_eq!(date.number_value(scope).unwrap(), 3.0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn symbol() {
|
||||
let _setup_guard = setup();
|
||||
let isolate = &mut v8::Isolate::new(Default::default());
|
||||
let scope = &mut v8::HandleScope::new(isolate);
|
||||
let context = v8::Context::new(scope);
|
||||
let scope = &mut v8::ContextScope::new(scope, context);
|
||||
|
||||
let desc = v8::String::new(scope, "a description").unwrap();
|
||||
|
||||
let s = v8::Symbol::new(scope, None);
|
||||
assert!(s.description(scope) == v8::undefined(scope));
|
||||
|
||||
let s = v8::Symbol::new(scope, Some(desc));
|
||||
assert!(s.description(scope) == desc);
|
||||
|
||||
let s_pub = v8::Symbol::for_global(scope, desc);
|
||||
assert!(s_pub.description(scope) == desc);
|
||||
assert!(s_pub != s);
|
||||
|
||||
let s_pub2 = v8::Symbol::for_global(scope, desc);
|
||||
assert!(s_pub2 != s);
|
||||
assert!(s_pub == s_pub2);
|
||||
|
||||
let s = eval(scope, "Symbol.asyncIterator").unwrap();
|
||||
assert!(s == v8::Symbol::get_async_iterator(scope));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn private() {
|
||||
let _setup_guard = setup();
|
||||
let isolate = &mut v8::Isolate::new(Default::default());
|
||||
let scope = &mut v8::HandleScope::new(isolate);
|
||||
let context = v8::Context::new(scope);
|
||||
let scope = &mut v8::ContextScope::new(scope, context);
|
||||
|
||||
let p = v8::Private::new(scope, None);
|
||||
assert!(p.name(scope) == v8::undefined(scope));
|
||||
|
||||
let name = v8::String::new(scope, "a name").unwrap();
|
||||
let p = v8::Private::new(scope, Some(name));
|
||||
assert!(p.name(scope) == name);
|
||||
|
||||
let p_api = v8::Private::for_api(scope, Some(name));
|
||||
assert!(p_api.name(scope) == name);
|
||||
assert!(p_api != p);
|
||||
|
||||
let p_api2 = v8::Private::for_api(scope, Some(name));
|
||||
assert!(p_api2 != p);
|
||||
assert!(p_api == p_api2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bigint() {
|
||||
let _setup_guard = setup();
|
||||
let isolate = &mut v8::Isolate::new(Default::default());
|
||||
let scope = &mut v8::HandleScope::new(isolate);
|
||||
let context = v8::Context::new(scope);
|
||||
let scope = &mut v8::ContextScope::new(scope, context);
|
||||
|
||||
let b = v8::BigInt::new_from_u64(scope, 1337);
|
||||
assert_eq!(b.u64_value(), (1337, true));
|
||||
|
||||
let b = v8::BigInt::new_from_i64(scope, -1337);
|
||||
assert_eq!(b.i64_value(), (-1337, true));
|
||||
|
||||
let words = vec![10, 10];
|
||||
let b = v8::BigInt::new_from_words(scope, false, &words).unwrap();
|
||||
assert_eq!(b.i64_value(), (10, false));
|
||||
|
||||
let raw_b = eval(scope, "184467440737095516170n").unwrap();
|
||||
assert!(b == raw_b);
|
||||
|
||||
let b = v8::BigInt::new_from_words(scope, true, &words).unwrap();
|
||||
assert_eq!(b.i64_value(), (-10, false));
|
||||
|
||||
let raw_b = eval(scope, "-184467440737095516170n").unwrap();
|
||||
assert!(b == raw_b);
|
||||
|
||||
let raw_b = v8::Local::<v8::BigInt>::try_from(raw_b).unwrap();
|
||||
|
||||
let mut vec = Vec::new();
|
||||
vec.resize(raw_b.word_count(), 0);
|
||||
assert_eq!(raw_b.to_words_array(&mut vec), (true, &mut [10, 10][..]));
|
||||
|
||||
let mut vec = Vec::new();
|
||||
vec.resize(1, 0);
|
||||
assert_eq!(raw_b.to_words_array(&mut vec), (true, &mut [10][..]));
|
||||
|
||||
let mut vec = Vec::new();
|
||||
vec.resize(20, 1337);
|
||||
assert_eq!(raw_b.to_words_array(&mut vec), (true, &mut [10, 10][..]));
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue