commit
c668f8dd8e
13 changed files with 152 additions and 167 deletions
|
@ -93,8 +93,7 @@ pub fn js_function(attr: TokenStream, input: TokenStream) -> TokenStream {
|
|||
use std::ffi::CString;
|
||||
use napi::{JsUnknown, Env, Error, Status, NapiValue, CallContext};
|
||||
let mut argc = #arg_len_span as usize;
|
||||
let mut raw_args =
|
||||
unsafe { mem::MaybeUninit::<[napi::sys::napi_value; #arg_len_span as usize]>::uninit().assume_init() };
|
||||
let mut raw_args: [napi::sys::napi_value; #arg_len_span] = [ptr::null_mut(); #arg_len_span];
|
||||
let mut raw_this = ptr::null_mut();
|
||||
|
||||
let mut has_error = false;
|
||||
|
@ -112,19 +111,19 @@ pub fn js_function(attr: TokenStream, input: TokenStream) -> TokenStream {
|
|||
}
|
||||
|
||||
let mut env = Env::from_raw(raw_env);
|
||||
match CallContext::new(&mut env, cb_info, raw_this, &raw_args, #arg_len_span, argc as usize)
|
||||
.and_then(|ctx| panic::catch_unwind(AssertUnwindSafe(move || #new_fn_name(ctx))).map_err(|e| {
|
||||
let message = {
|
||||
if let Some(string) = e.downcast_ref::<String>() {
|
||||
string.clone()
|
||||
} else if let Some(string) = e.downcast_ref::<&str>() {
|
||||
string.to_string()
|
||||
} else {
|
||||
format!("panic from Rust code: {:?}", e)
|
||||
}
|
||||
};
|
||||
Error::from_reason(message)
|
||||
}).and_then(|v| v))
|
||||
let ctx = CallContext::new(&mut env, cb_info, raw_this, &raw_args, #arg_len_span, argc as usize);
|
||||
match panic::catch_unwind(AssertUnwindSafe(move || #new_fn_name(ctx))).map_err(|e| {
|
||||
let message = {
|
||||
if let Some(string) = e.downcast_ref::<String>() {
|
||||
string.clone()
|
||||
} else if let Some(string) = e.downcast_ref::<&str>() {
|
||||
string.to_string()
|
||||
} else {
|
||||
format!("panic from Rust code: {:?}", e)
|
||||
}
|
||||
};
|
||||
Error::from_reason(message)
|
||||
}).and_then(|v| v)
|
||||
{
|
||||
Ok(v) => v.raw_value(),
|
||||
Err(e) => {
|
||||
|
|
|
@ -4,54 +4,76 @@ use std::ptr;
|
|||
|
||||
use crate::error::check_status;
|
||||
use crate::js_values::NapiValue;
|
||||
use crate::{sys, Env, Result, Task};
|
||||
use crate::{sys, Env, JsObject, Result, Task};
|
||||
|
||||
pub struct AsyncWork<T: Task> {
|
||||
struct AsyncWork<T: Task> {
|
||||
inner_task: T,
|
||||
deferred: sys::napi_deferred,
|
||||
value: Result<*mut T::Output>,
|
||||
value: Result<mem::MaybeUninit<T::Output>>,
|
||||
napi_async_work: sys::napi_async_work,
|
||||
}
|
||||
|
||||
impl<T: Task> AsyncWork<T> {
|
||||
pub fn run(env: sys::napi_env, task: T, deferred: sys::napi_deferred) -> Result<()> {
|
||||
let mut raw_resource = ptr::null_mut();
|
||||
check_status(unsafe { sys::napi_create_object(env, &mut raw_resource) })?;
|
||||
let mut raw_name = ptr::null_mut();
|
||||
let s = "napi_rs_async";
|
||||
check_status(unsafe {
|
||||
sys::napi_create_string_utf8(
|
||||
env,
|
||||
s.as_ptr() as *const c_char,
|
||||
s.len() as u64,
|
||||
&mut raw_name,
|
||||
)
|
||||
})?;
|
||||
let result = AsyncWork {
|
||||
inner_task: task,
|
||||
deferred,
|
||||
value: Ok(ptr::null_mut()),
|
||||
};
|
||||
let mut async_work = ptr::null_mut();
|
||||
check_status(unsafe {
|
||||
sys::napi_create_async_work(
|
||||
env,
|
||||
raw_resource,
|
||||
raw_name,
|
||||
Some(execute::<T> as unsafe extern "C" fn(env: sys::napi_env, data: *mut c_void)),
|
||||
Some(
|
||||
complete::<T>
|
||||
as unsafe extern "C" fn(
|
||||
env: sys::napi_env,
|
||||
status: sys::napi_status,
|
||||
data: *mut c_void,
|
||||
),
|
||||
),
|
||||
Box::leak(Box::new(result)) as *mut _ as *mut c_void,
|
||||
&mut async_work,
|
||||
)
|
||||
})?;
|
||||
check_status(unsafe { sys::napi_queue_async_work(env, async_work) })
|
||||
#[derive(Debug)]
|
||||
pub struct AsyncWorkPromise<'env> {
|
||||
napi_async_work: sys::napi_async_work,
|
||||
raw_promise: sys::napi_value,
|
||||
env: &'env Env,
|
||||
}
|
||||
|
||||
impl<'env> AsyncWorkPromise<'env> {
|
||||
#[inline(always)]
|
||||
pub fn promise_object(&self) -> JsObject {
|
||||
JsObject::from_raw_unchecked(self.env.0, self.raw_promise)
|
||||
}
|
||||
|
||||
pub fn cancel(self) -> Result<()> {
|
||||
check_status(unsafe { sys::napi_cancel_async_work(self.env.0, self.napi_async_work) })
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn run<'env, T: Task>(env: &'env Env, task: T) -> Result<AsyncWorkPromise<'env>> {
|
||||
let mut raw_resource = ptr::null_mut();
|
||||
check_status(unsafe { sys::napi_create_object(env.0, &mut raw_resource) })?;
|
||||
let mut raw_promise = ptr::null_mut();
|
||||
let mut deferred = ptr::null_mut();
|
||||
check_status(unsafe { sys::napi_create_promise(env.0, &mut deferred, &mut raw_promise) })?;
|
||||
let mut raw_name = ptr::null_mut();
|
||||
let s = "napi_rs_async_work";
|
||||
check_status(unsafe {
|
||||
sys::napi_create_string_utf8(
|
||||
env.0,
|
||||
s.as_ptr() as *const c_char,
|
||||
s.len() as u64,
|
||||
&mut raw_name,
|
||||
)
|
||||
})?;
|
||||
let result = Box::leak(Box::new(AsyncWork {
|
||||
inner_task: task,
|
||||
deferred,
|
||||
value: Ok(mem::MaybeUninit::zeroed()),
|
||||
napi_async_work: ptr::null_mut(),
|
||||
}));
|
||||
check_status(unsafe {
|
||||
sys::napi_create_async_work(
|
||||
env.0,
|
||||
raw_resource,
|
||||
raw_name,
|
||||
Some(execute::<T> as unsafe extern "C" fn(env: sys::napi_env, data: *mut c_void)),
|
||||
Some(
|
||||
complete::<T>
|
||||
as unsafe extern "C" fn(env: sys::napi_env, status: sys::napi_status, data: *mut c_void),
|
||||
),
|
||||
result as *mut _ as *mut c_void,
|
||||
&mut result.napi_async_work,
|
||||
)
|
||||
})?;
|
||||
check_status(unsafe { sys::napi_queue_async_work(env.0, result.napi_async_work) })?;
|
||||
Ok(AsyncWorkPromise {
|
||||
napi_async_work: result.napi_async_work,
|
||||
raw_promise,
|
||||
env,
|
||||
})
|
||||
}
|
||||
|
||||
unsafe impl<T: Task> Send for AsyncWork<T> {}
|
||||
|
@ -60,10 +82,10 @@ unsafe impl<T: Task> Sync for AsyncWork<T> {}
|
|||
|
||||
unsafe extern "C" fn execute<T: Task>(_env: sys::napi_env, data: *mut c_void) {
|
||||
let mut work = Box::from_raw(data as *mut AsyncWork<T>);
|
||||
work.value = work
|
||||
.inner_task
|
||||
.compute()
|
||||
.map(|v| Box::into_raw(Box::from(v)));
|
||||
let _ = mem::replace(
|
||||
&mut work.value,
|
||||
work.inner_task.compute().map(|v| mem::MaybeUninit::new(v)),
|
||||
);
|
||||
Box::leak(work);
|
||||
}
|
||||
|
||||
|
@ -73,37 +95,26 @@ unsafe extern "C" fn complete<T: Task>(
|
|||
data: *mut c_void,
|
||||
) {
|
||||
let mut work = Box::from_raw(data as *mut AsyncWork<T>);
|
||||
let value_ptr = mem::replace(&mut work.value, Ok(ptr::null_mut()));
|
||||
let value_ptr = mem::replace(&mut work.value, Ok(mem::MaybeUninit::zeroed()));
|
||||
let deferred = mem::replace(&mut work.deferred, ptr::null_mut());
|
||||
let napi_async_work = mem::replace(&mut work.napi_async_work, ptr::null_mut());
|
||||
let value = value_ptr.and_then(move |v| {
|
||||
let mut env = Env::from_raw(env);
|
||||
let output = ptr::read(v as *const _);
|
||||
work.inner_task.resolve(&mut env, output)
|
||||
let output = v.assume_init();
|
||||
work.inner_task.resolve(&mut Env::from_raw(env), output)
|
||||
});
|
||||
let mut handle_scope = ptr::null_mut();
|
||||
match check_status(status).and_then(move |_| value) {
|
||||
Ok(v) => {
|
||||
let open_handle_status = sys::napi_open_handle_scope(env, &mut handle_scope);
|
||||
debug_assert!(
|
||||
open_handle_status == sys::napi_status::napi_ok,
|
||||
"OpenHandleScope failed"
|
||||
);
|
||||
let status = sys::napi_resolve_deferred(env, deferred, v.raw_value());
|
||||
debug_assert!(status == sys::napi_status::napi_ok, "Reject promise failed");
|
||||
}
|
||||
Err(e) => {
|
||||
let open_handle_status = sys::napi_open_handle_scope(env, &mut handle_scope);
|
||||
debug_assert!(
|
||||
open_handle_status == sys::napi_status::napi_ok,
|
||||
"OpenHandleScope failed"
|
||||
);
|
||||
let status = sys::napi_reject_deferred(env, deferred, e.into_raw(env));
|
||||
debug_assert!(status == sys::napi_status::napi_ok, "Reject promise failed");
|
||||
}
|
||||
};
|
||||
let close_handle_scope_status = sys::napi_close_handle_scope(env, handle_scope);
|
||||
let delete_status = sys::napi_delete_async_work(env, napi_async_work);
|
||||
debug_assert!(
|
||||
close_handle_scope_status == sys::napi_status::napi_ok,
|
||||
"Close handle scope failed"
|
||||
delete_status == sys::napi_status::napi_ok,
|
||||
"Delete async work failed"
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,34 +1,34 @@
|
|||
use std::ptr;
|
||||
|
||||
use crate::error::check_status;
|
||||
use crate::{sys, Either, Env, Error, JsUndefined, JsUnknown, NapiValue, Result, Status};
|
||||
use crate::{sys, Either, Env, Error, JsUndefined, NapiValue, Result, Status};
|
||||
|
||||
pub struct CallContext<'env, T: NapiValue = JsUnknown> {
|
||||
pub struct CallContext<'env> {
|
||||
pub env: &'env Env,
|
||||
pub this: T,
|
||||
raw_this: sys::napi_value,
|
||||
callback_info: sys::napi_callback_info,
|
||||
args: &'env [sys::napi_value],
|
||||
arg_len: usize,
|
||||
actual_arg_length: usize,
|
||||
}
|
||||
|
||||
impl<'env, T: NapiValue> CallContext<'env, T> {
|
||||
impl<'env> CallContext<'env> {
|
||||
pub fn new(
|
||||
env: &'env Env,
|
||||
callback_info: sys::napi_callback_info,
|
||||
this: sys::napi_value,
|
||||
raw_this: sys::napi_value,
|
||||
args: &'env [sys::napi_value],
|
||||
arg_len: usize,
|
||||
actual_arg_length: usize,
|
||||
) -> Result<Self> {
|
||||
Ok(Self {
|
||||
) -> Self {
|
||||
Self {
|
||||
env,
|
||||
callback_info,
|
||||
this: T::from_raw(env.0, this)?,
|
||||
raw_this,
|
||||
args,
|
||||
arg_len,
|
||||
actual_arg_length,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get<ArgType: NapiValue>(&self, index: usize) -> Result<ArgType> {
|
||||
|
@ -38,10 +38,7 @@ impl<'env, T: NapiValue> CallContext<'env, T> {
|
|||
reason: "Arguments index out of range".to_owned(),
|
||||
})
|
||||
} else {
|
||||
Ok(ArgType::from_raw_without_typecheck(
|
||||
self.env.0,
|
||||
self.args[index],
|
||||
))
|
||||
Ok(ArgType::from_raw_unchecked(self.env.0, self.args[index]))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,4 +65,14 @@ impl<'env, T: NapiValue> CallContext<'env, T> {
|
|||
check_status(unsafe { sys::napi_get_new_target(self.env.0, self.callback_info, &mut value) })?;
|
||||
V::from_raw(self.env.0, value)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn this<T: NapiValue>(&self) -> Result<T> {
|
||||
T::from_raw(self.env.0, self.raw_this)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn this_unchecked<T: NapiValue>(&self) -> T {
|
||||
T::from_raw_unchecked(self.env.0, self.raw_this)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ use std::mem;
|
|||
use std::os::raw::{c_char, c_void};
|
||||
use std::ptr;
|
||||
|
||||
use crate::async_work::AsyncWork;
|
||||
use crate::async_work::{self, AsyncWorkPromise};
|
||||
use crate::error::check_status;
|
||||
use crate::js_values::*;
|
||||
use crate::task::Task;
|
||||
|
@ -40,8 +40,7 @@ impl Env {
|
|||
|
||||
pub fn get_undefined(&self) -> Result<JsUndefined> {
|
||||
let mut raw_value = ptr::null_mut();
|
||||
let status = unsafe { sys::napi_get_undefined(self.0, &mut raw_value) };
|
||||
check_status(status)?;
|
||||
check_status(unsafe { sys::napi_get_undefined(self.0, &mut raw_value) })?;
|
||||
Ok(JsUndefined::from_raw_unchecked(self.0, raw_value))
|
||||
}
|
||||
|
||||
|
@ -220,7 +219,7 @@ impl Env {
|
|||
Ok(JsObject::from_raw_unchecked(self.0, raw_value))
|
||||
}
|
||||
|
||||
pub fn create_buffer(&self, length: u64) -> Result<JsBuffer> {
|
||||
pub fn create_buffer<'env, 'buffer>(&'env self, length: u64) -> Result<JsBuffer<'buffer>> {
|
||||
let mut raw_value = ptr::null_mut();
|
||||
let mut data = Vec::with_capacity(length as usize);
|
||||
let mut data_ptr = data.as_mut_ptr();
|
||||
|
@ -229,7 +228,7 @@ impl Env {
|
|||
})?;
|
||||
mem::forget(data);
|
||||
|
||||
Ok(JsBuffer::from_raw_unchecked(
|
||||
Ok(JsBuffer::new(
|
||||
self.0,
|
||||
raw_value,
|
||||
data_ptr as *mut u8,
|
||||
|
@ -237,7 +236,10 @@ impl Env {
|
|||
))
|
||||
}
|
||||
|
||||
pub fn create_buffer_with_data(&self, mut data: Vec<u8>) -> Result<JsBuffer> {
|
||||
pub fn create_buffer_with_data<'env, 'buffer>(
|
||||
&'env self,
|
||||
mut data: Vec<u8>,
|
||||
) -> Result<JsBuffer<'buffer>> {
|
||||
let length = data.len() as u64;
|
||||
let mut raw_value = ptr::null_mut();
|
||||
let data_ptr = data.as_mut_ptr();
|
||||
|
@ -254,12 +256,7 @@ impl Env {
|
|||
let mut changed = 0;
|
||||
check_status(unsafe { sys::napi_adjust_external_memory(self.0, length as i64, &mut changed) })?;
|
||||
mem::forget(data);
|
||||
Ok(JsBuffer::from_raw_unchecked(
|
||||
self.0,
|
||||
raw_value,
|
||||
data_ptr,
|
||||
length as usize,
|
||||
))
|
||||
Ok(JsBuffer::new(self.0, raw_value, data_ptr, length as usize))
|
||||
}
|
||||
|
||||
pub fn create_arraybuffer(&self, length: u64) -> Result<JsArrayBuffer> {
|
||||
|
@ -490,13 +487,8 @@ impl Env {
|
|||
Ok(JsObject::from_raw_unchecked(self.0, result))
|
||||
}
|
||||
|
||||
pub fn spawn<T: 'static + Task>(&self, task: T) -> Result<JsObject> {
|
||||
let mut raw_promise = ptr::null_mut();
|
||||
let mut raw_deferred = ptr::null_mut();
|
||||
|
||||
check_status(unsafe { sys::napi_create_promise(self.0, &mut raw_deferred, &mut raw_promise) })?;
|
||||
AsyncWork::run(self.0, task, raw_deferred)?;
|
||||
Ok(JsObject::from_raw_unchecked(self.0, raw_promise))
|
||||
pub fn spawn<T: 'static + Task>(&self, task: T) -> Result<AsyncWorkPromise> {
|
||||
async_work::run(self, task)
|
||||
}
|
||||
|
||||
pub fn get_global(&self) -> Result<JsObject> {
|
||||
|
|
|
@ -154,7 +154,7 @@ impl NapiValue for JsArrayBuffer {
|
|||
})
|
||||
}
|
||||
|
||||
fn from_raw_without_typecheck(env: sys::napi_env, value: sys::napi_value) -> Self {
|
||||
fn from_raw_unchecked(env: sys::napi_env, value: sys::napi_value) -> Self {
|
||||
let mut data = ptr::null_mut();
|
||||
let mut len: u64 = 0;
|
||||
let status = unsafe { sys::napi_get_arraybuffer_info(env, value, &mut data, &mut len) };
|
||||
|
|
|
@ -154,7 +154,7 @@ impl NapiValue for JsBigint {
|
|||
})
|
||||
}
|
||||
|
||||
fn from_raw_without_typecheck(env: sys::napi_env, value: sys::napi_value) -> Self {
|
||||
fn from_raw_unchecked(env: sys::napi_env, value: sys::napi_value) -> Self {
|
||||
let mut word_count: u64 = 0;
|
||||
let status = unsafe {
|
||||
sys::napi_get_value_bigint_words(
|
||||
|
|
|
@ -8,18 +8,13 @@ use crate::error::check_status;
|
|||
use crate::{sys, Error, Result};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct JsBuffer {
|
||||
pub struct JsBuffer<'buffer> {
|
||||
pub value: JsObject,
|
||||
pub data: &'static [u8],
|
||||
pub data: &'buffer [u8],
|
||||
}
|
||||
|
||||
impl JsBuffer {
|
||||
pub(crate) fn from_raw_unchecked(
|
||||
env: sys::napi_env,
|
||||
value: sys::napi_value,
|
||||
data: *mut u8,
|
||||
len: usize,
|
||||
) -> Self {
|
||||
impl<'buffer> JsBuffer<'buffer> {
|
||||
pub(crate) fn new(env: sys::napi_env, value: sys::napi_value, data: *mut u8, len: usize) -> Self {
|
||||
Self {
|
||||
value: JsObject(Value {
|
||||
env,
|
||||
|
@ -139,7 +134,7 @@ impl JsBuffer {
|
|||
}
|
||||
}
|
||||
|
||||
impl NapiValue for JsBuffer {
|
||||
impl<'buffer> NapiValue for JsBuffer<'buffer> {
|
||||
fn raw_value(&self) -> sys::napi_value {
|
||||
self.value.0.value
|
||||
}
|
||||
|
@ -158,7 +153,7 @@ impl NapiValue for JsBuffer {
|
|||
})
|
||||
}
|
||||
|
||||
fn from_raw_without_typecheck(env: sys::napi_env, value: sys::napi_value) -> Self {
|
||||
fn from_raw_unchecked(env: sys::napi_env, value: sys::napi_value) -> Self {
|
||||
let mut data = ptr::null_mut();
|
||||
let mut len: u64 = 0;
|
||||
let status = unsafe { sys::napi_get_buffer_info(env, value, &mut data, &mut len) };
|
||||
|
@ -177,13 +172,13 @@ impl NapiValue for JsBuffer {
|
|||
}
|
||||
}
|
||||
|
||||
impl AsRef<[u8]> for JsBuffer {
|
||||
impl<'buffer> AsRef<[u8]> for JsBuffer<'buffer> {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
self.data
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for JsBuffer {
|
||||
impl<'buffer> Deref for JsBuffer<'buffer> {
|
||||
type Target = [u8];
|
||||
|
||||
fn deref(&self) -> &[u8] {
|
||||
|
@ -191,9 +186,9 @@ impl Deref for JsBuffer {
|
|||
}
|
||||
}
|
||||
|
||||
impl TryFrom<JsUnknown> for JsBuffer {
|
||||
impl<'buffer> TryFrom<JsUnknown> for JsBuffer<'buffer> {
|
||||
type Error = Error;
|
||||
fn try_from(value: JsUnknown) -> Result<JsBuffer> {
|
||||
fn try_from(value: JsUnknown) -> Result<JsBuffer<'buffer>> {
|
||||
JsBuffer::from_raw(value.0.env, value.0.value)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ impl<A: NapiValue, B: NapiValue> NapiValue for Either<A, B> {
|
|||
.or_else(|_| B::from_raw(env, value).map(Self::B))
|
||||
}
|
||||
|
||||
fn from_raw_without_typecheck(env: sys::napi_env, value: sys::napi_value) -> Either<A, B> {
|
||||
fn from_raw_unchecked(env: sys::napi_env, value: sys::napi_value) -> Either<A, B> {
|
||||
Self::from_raw(env, value).unwrap()
|
||||
}
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ macro_rules! impl_napi_value_trait {
|
|||
self.0.value
|
||||
}
|
||||
|
||||
fn from_raw_without_typecheck(env: sys::napi_env, value: sys::napi_value) -> $js_value {
|
||||
fn from_raw_unchecked(env: sys::napi_env, value: sys::napi_value) -> $js_value {
|
||||
$js_value(Value {
|
||||
env,
|
||||
value,
|
||||
|
@ -101,17 +101,6 @@ macro_rules! impl_napi_value_trait {
|
|||
}
|
||||
}
|
||||
|
||||
impl $js_value {
|
||||
#[inline]
|
||||
pub fn from_raw_unchecked(env: sys::napi_env, value: sys::napi_value) -> Self {
|
||||
Self(Value {
|
||||
env,
|
||||
value,
|
||||
value_type: $value_type,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<JsUnknown> for $js_value {
|
||||
type Error = Error;
|
||||
fn try_from(value: JsUnknown) -> Result<$js_value> {
|
||||
|
@ -231,7 +220,7 @@ macro_rules! impl_js_value_methods {
|
|||
pub trait NapiValue: Sized {
|
||||
fn from_raw(env: sys::napi_env, value: sys::napi_value) -> Result<Self>;
|
||||
|
||||
fn from_raw_without_typecheck(env: sys::napi_env, value: sys::napi_value) -> Self;
|
||||
fn from_raw_unchecked(env: sys::napi_env, value: sys::napi_value) -> Self;
|
||||
|
||||
fn raw_value(&self) -> sys::napi_value;
|
||||
}
|
||||
|
@ -268,7 +257,7 @@ impl NapiValue for JsUnknown {
|
|||
}))
|
||||
}
|
||||
|
||||
fn from_raw_without_typecheck(env: sys::napi_env, value: sys::napi_value) -> Self {
|
||||
fn from_raw_unchecked(env: sys::napi_env, value: sys::napi_value) -> Self {
|
||||
JsUnknown(Value {
|
||||
env,
|
||||
value,
|
||||
|
|
|
@ -12,24 +12,19 @@ fn create_test_class(ctx: CallContext) -> Result<JsFunction> {
|
|||
}
|
||||
|
||||
#[js_function(1)]
|
||||
fn test_class_constructor(mut ctx: CallContext<JsObject>) -> Result<JsUndefined> {
|
||||
fn test_class_constructor(ctx: CallContext) -> Result<JsUndefined> {
|
||||
let count = ctx.get::<JsNumber>(0)?;
|
||||
ctx
|
||||
.this
|
||||
.set_named_property("count", ctx.env.create_int32(count.try_into()?)?)?;
|
||||
let mut this: JsObject = ctx.this_unchecked();
|
||||
this.set_named_property("count", ctx.env.create_int32(count.try_into()?)?)?;
|
||||
ctx.env.get_undefined()
|
||||
}
|
||||
|
||||
#[js_function(1)]
|
||||
fn add_count(mut ctx: CallContext<JsObject>) -> Result<JsUndefined> {
|
||||
fn add_count(ctx: CallContext) -> Result<JsUndefined> {
|
||||
let add: i32 = ctx.get::<JsNumber>(0)?.try_into()?;
|
||||
let count: i32 = ctx
|
||||
.this
|
||||
.get_named_property::<JsNumber>("count")?
|
||||
.try_into()?;
|
||||
ctx
|
||||
.this
|
||||
.set_named_property("count", ctx.env.create_int32(count + add)?)?;
|
||||
let mut this: JsObject = ctx.this_unchecked();
|
||||
let count: i32 = this.get_named_property::<JsNumber>("count")?.try_into()?;
|
||||
this.set_named_property("count", ctx.env.create_int32(count + add)?)?;
|
||||
ctx.env.get_undefined()
|
||||
}
|
||||
|
||||
|
|
|
@ -12,11 +12,11 @@ pub fn call_function(ctx: CallContext) -> Result<JsNull> {
|
|||
}
|
||||
|
||||
#[js_function(1)]
|
||||
pub fn call_function_with_this(ctx: CallContext<JsObject>) -> Result<JsNull> {
|
||||
let js_this = &ctx.this;
|
||||
pub fn call_function_with_this(ctx: CallContext) -> Result<JsNull> {
|
||||
let js_this: JsObject = ctx.this_unchecked();
|
||||
let js_func = ctx.get::<JsFunction>(0)?;
|
||||
|
||||
js_func.call(Some(js_this), &[])?;
|
||||
js_func.call(Some(&js_this), &[])?;
|
||||
|
||||
ctx.env.get_null()
|
||||
}
|
||||
|
|
|
@ -139,15 +139,11 @@ fn test_define_properties(ctx: CallContext) -> Result<JsUndefined> {
|
|||
}
|
||||
|
||||
#[js_function(1)]
|
||||
fn add(mut ctx: CallContext<JsObject>) -> Result<JsUndefined> {
|
||||
let count: i32 = ctx
|
||||
.this
|
||||
.get_named_property::<JsNumber>("count")?
|
||||
.try_into()?;
|
||||
fn add(ctx: CallContext) -> Result<JsUndefined> {
|
||||
let mut this: JsObject = ctx.this_unchecked();
|
||||
let count: i32 = this.get_named_property::<JsNumber>("count")?.try_into()?;
|
||||
let value_to_add: i32 = ctx.get::<JsNumber>(0)?.try_into()?;
|
||||
ctx
|
||||
.this
|
||||
.set_named_property("count", ctx.env.create_int32(count + value_to_add)?)?;
|
||||
this.set_named_property("count", ctx.env.create_int32(count + value_to_add)?)?;
|
||||
ctx.env.get_undefined()
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,8 @@ fn fibonacci_native(n: u32) -> u32 {
|
|||
fn test_spawn_thread(ctx: CallContext) -> Result<JsObject> {
|
||||
let n = ctx.get::<JsNumber>(0)?;
|
||||
let task = ComputeFib::new(n.try_into()?);
|
||||
ctx.env.spawn(task)
|
||||
let async_promise = ctx.env.spawn(task)?;
|
||||
Ok(async_promise.promise_object())
|
||||
}
|
||||
|
||||
pub fn register_js(module: &mut Module) -> Result<()> {
|
||||
|
|
Loading…
Reference in a new issue