mirror of
https://github.com/denoland/deno.git
synced 2025-01-11 16:42:21 -05:00
build: require safety comments on unsafe code (#13870)
Co-authored-by: Bartek Iwańczuk <biwanczuk@gmail.com> Co-authored-by: Divy Srivastava <dj.srivastava23@gmail.com>
This commit is contained in:
parent
38505db391
commit
8d82ba7299
29 changed files with 294 additions and 87 deletions
|
@ -153,11 +153,13 @@ fn run(
|
||||||
fn get_port() -> u16 {
|
fn get_port() -> u16 {
|
||||||
static mut NEXT_PORT: u16 = 4544;
|
static mut NEXT_PORT: u16 = 4544;
|
||||||
|
|
||||||
let port = unsafe { NEXT_PORT };
|
// TODO(bartlomieju):
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
unsafe {
|
let port = unsafe {
|
||||||
|
let p = NEXT_PORT;
|
||||||
NEXT_PORT += 1;
|
NEXT_PORT += 1;
|
||||||
}
|
p
|
||||||
|
};
|
||||||
|
|
||||||
port
|
port
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,13 @@ mod dirs {
|
||||||
pub fn home_dir() -> Option<PathBuf> {
|
pub fn home_dir() -> Option<PathBuf> {
|
||||||
std::env::var_os("HOME")
|
std::env::var_os("HOME")
|
||||||
.and_then(|h| if h.is_empty() { None } else { Some(h) })
|
.and_then(|h| if h.is_empty() { None } else { Some(h) })
|
||||||
.or_else(|| unsafe { fallback() })
|
.or_else(|| {
|
||||||
|
// TODO(bartlomieju):
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
|
unsafe {
|
||||||
|
fallback()
|
||||||
|
}
|
||||||
|
})
|
||||||
.map(PathBuf::from)
|
.map(PathBuf::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,11 @@ pub fn set_lsp_log_level(level: log::Level) {
|
||||||
|
|
||||||
pub fn lsp_log_level() -> log::Level {
|
pub fn lsp_log_level() -> log::Level {
|
||||||
let level = LSP_LOG_LEVEL.load(Ordering::SeqCst);
|
let level = LSP_LOG_LEVEL.load(Ordering::SeqCst);
|
||||||
unsafe { std::mem::transmute(level) }
|
// TODO(bartlomieju):
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
|
unsafe {
|
||||||
|
std::mem::transmute(level)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Use this macro to do "info" logs in the lsp code. This allows
|
/// Use this macro to do "info" logs in the lsp code. This allows
|
||||||
|
|
|
@ -20,6 +20,8 @@ pub fn start(parent_process_id: u32) {
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
fn is_process_active(process_id: u32) -> bool {
|
fn is_process_active(process_id: u32) -> bool {
|
||||||
|
// TODO(bartlomieju):
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
unsafe {
|
unsafe {
|
||||||
// signal of 0 checks for the existence of the process id
|
// signal of 0 checks for the existence of the process id
|
||||||
libc::kill(process_id as i32, 0) == 0
|
libc::kill(process_id as i32, 0) == 0
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
/// This is the difference between `ulimit -n` and `ulimit -n -H`.
|
/// This is the difference between `ulimit -n` and `ulimit -n -H`.
|
||||||
pub fn raise_fd_limit() {
|
pub fn raise_fd_limit() {
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
|
// TODO(bartlomieju):
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut limits = libc::rlimit {
|
let mut limits = libc::rlimit {
|
||||||
rlim_cur: 0,
|
rlim_cur: 0,
|
||||||
|
|
|
@ -302,13 +302,19 @@ mod internal {
|
||||||
Some((head, rc)) => {
|
Some((head, rc)) => {
|
||||||
// Register this `Cancelable` node with a `CancelHandle` head node.
|
// Register this `Cancelable` node with a `CancelHandle` head node.
|
||||||
assert_ne!(self, head);
|
assert_ne!(self, head);
|
||||||
|
// TODO(piscisaureus): safety comment
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
let self_inner = unsafe { &mut *self.inner.get() };
|
let self_inner = unsafe { &mut *self.inner.get() };
|
||||||
|
// TODO(piscisaureus): safety comment
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
let head_inner = unsafe { &mut *head.inner.get() };
|
let head_inner = unsafe { &mut *head.inner.get() };
|
||||||
self_inner.link(waker, head_inner, rc)
|
self_inner.link(waker, head_inner, rc)
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// This `Cancelable` has already been linked to a `CancelHandle` head
|
// This `Cancelable` has already been linked to a `CancelHandle` head
|
||||||
// node; just update our stored `Waker` if necessary.
|
// node; just update our stored `Waker` if necessary.
|
||||||
|
// TODO(piscisaureus): safety comment
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
let inner = unsafe { &mut *self.inner.get() };
|
let inner = unsafe { &mut *self.inner.get() };
|
||||||
inner.update_waker(waker)
|
inner.update_waker(waker)
|
||||||
}
|
}
|
||||||
|
@ -316,11 +322,15 @@ mod internal {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cancel(&self) {
|
pub fn cancel(&self) {
|
||||||
|
// TODO(piscisaureus): safety comment
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
let inner = unsafe { &mut *self.inner.get() };
|
let inner = unsafe { &mut *self.inner.get() };
|
||||||
inner.cancel();
|
inner.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_canceled(&self) -> bool {
|
pub fn is_canceled(&self) -> bool {
|
||||||
|
// TODO(piscisaureus): safety comment
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
let inner = unsafe { &mut *self.inner.get() };
|
let inner = unsafe { &mut *self.inner.get() };
|
||||||
inner.is_canceled()
|
inner.is_canceled()
|
||||||
}
|
}
|
||||||
|
@ -337,6 +347,8 @@ mod internal {
|
||||||
|
|
||||||
impl Drop for Node {
|
impl Drop for Node {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
|
// TODO(piscisaureus): safety comment
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
let inner = unsafe { &mut *self.inner.get() };
|
let inner = unsafe { &mut *self.inner.get() };
|
||||||
inner.unlink();
|
inner.unlink();
|
||||||
}
|
}
|
||||||
|
@ -392,6 +404,8 @@ mod internal {
|
||||||
prev: next_prev_nn,
|
prev: next_prev_nn,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
|
// TODO(piscisaureus): safety comment
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
let prev = unsafe { &mut *next_prev_nn.as_ptr() };
|
let prev = unsafe { &mut *next_prev_nn.as_ptr() };
|
||||||
match prev {
|
match prev {
|
||||||
NodeInner::Linked {
|
NodeInner::Linked {
|
||||||
|
@ -444,10 +458,14 @@ mod internal {
|
||||||
if prev_nn == next_nn {
|
if prev_nn == next_nn {
|
||||||
// There were only two nodes in this chain; after unlinking ourselves
|
// There were only two nodes in this chain; after unlinking ourselves
|
||||||
// the other node is no longer linked.
|
// the other node is no longer linked.
|
||||||
|
// TODO(piscisaureus): safety comment
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
let other = unsafe { prev_nn.as_mut() };
|
let other = unsafe { prev_nn.as_mut() };
|
||||||
*other = NodeInner::Unlinked;
|
*other = NodeInner::Unlinked;
|
||||||
} else {
|
} else {
|
||||||
// The chain had more than two nodes.
|
// The chain had more than two nodes.
|
||||||
|
// TODO(piscisaureus): safety comment
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
match unsafe { prev_nn.as_mut() } {
|
match unsafe { prev_nn.as_mut() } {
|
||||||
NodeInner::Linked {
|
NodeInner::Linked {
|
||||||
next: prev_next_nn, ..
|
next: prev_next_nn, ..
|
||||||
|
@ -456,6 +474,8 @@ mod internal {
|
||||||
}
|
}
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
// TODO(piscisaureus): safety comment
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
match unsafe { next_nn.as_mut() } {
|
match unsafe { next_nn.as_mut() } {
|
||||||
NodeInner::Linked {
|
NodeInner::Linked {
|
||||||
prev: next_prev_nn, ..
|
prev: next_prev_nn, ..
|
||||||
|
@ -473,6 +493,8 @@ mod internal {
|
||||||
fn cancel(&mut self) {
|
fn cancel(&mut self) {
|
||||||
let mut head_nn = NonNull::from(self);
|
let mut head_nn = NonNull::from(self);
|
||||||
|
|
||||||
|
// TODO(piscisaureus): safety comment
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
// Mark the head node as canceled.
|
// Mark the head node as canceled.
|
||||||
let mut item_nn =
|
let mut item_nn =
|
||||||
match replace(unsafe { head_nn.as_mut() }, NodeInner::Canceled) {
|
match replace(unsafe { head_nn.as_mut() }, NodeInner::Canceled) {
|
||||||
|
@ -487,6 +509,8 @@ mod internal {
|
||||||
|
|
||||||
// Cancel all item nodes in the chain, waking each stored `Waker`.
|
// Cancel all item nodes in the chain, waking each stored `Waker`.
|
||||||
while item_nn != head_nn {
|
while item_nn != head_nn {
|
||||||
|
// TODO(piscisaureus): safety comment
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
match replace(unsafe { item_nn.as_mut() }, NodeInner::Canceled) {
|
match replace(unsafe { item_nn.as_mut() }, NodeInner::Canceled) {
|
||||||
NodeInner::Linked {
|
NodeInner::Linked {
|
||||||
kind: NodeKind::Item { waker },
|
kind: NodeKind::Item { waker },
|
||||||
|
@ -745,6 +769,7 @@ mod tests {
|
||||||
assert!(Rc::get_mut(&mut cancel_handle).is_some());
|
assert!(Rc::get_mut(&mut cancel_handle).is_some());
|
||||||
|
|
||||||
let mut future = pending::<Never>().or_cancel(&cancel_handle);
|
let mut future = pending::<Never>().or_cancel(&cancel_handle);
|
||||||
|
// SAFETY: `Cancelable` pins the future
|
||||||
let future = unsafe { Pin::new_unchecked(&mut future) };
|
let future = unsafe { Pin::new_unchecked(&mut future) };
|
||||||
|
|
||||||
// There are two `Rc<CancelHandle>` references now, so this fails.
|
// There are two `Rc<CancelHandle>` references now, so this fails.
|
||||||
|
|
|
@ -157,12 +157,16 @@ impl<T: 'static> RcRef<T> {
|
||||||
map_fn: F,
|
map_fn: F,
|
||||||
) -> RcRef<T> {
|
) -> RcRef<T> {
|
||||||
let RcRef::<S> { rc, value } = source.into();
|
let RcRef::<S> { rc, value } = source.into();
|
||||||
|
// TODO(piscisaureus): safety comment
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
let value = map_fn(unsafe { &*value });
|
let value = map_fn(unsafe { &*value });
|
||||||
RcRef { rc, value }
|
RcRef { rc, value }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn split(rc_ref: &Self) -> (&T, &Rc<dyn Any>) {
|
pub(crate) fn split(rc_ref: &Self) -> (&T, &Rc<dyn Any>) {
|
||||||
let &Self { ref rc, value } = rc_ref;
|
let &Self { ref rc, value } = rc_ref;
|
||||||
|
// TODO(piscisaureus): safety comment
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
(unsafe { &*value }, rc)
|
(unsafe { &*value }, rc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -206,7 +210,11 @@ impl<T: 'static> From<&Rc<T>> for RcRef<T> {
|
||||||
impl<T> Deref for RcRef<T> {
|
impl<T> Deref for RcRef<T> {
|
||||||
type Target = T;
|
type Target = T;
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
unsafe { &*self.value }
|
// TODO(piscisaureus): safety comment
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
|
unsafe {
|
||||||
|
&*self.value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,6 +268,8 @@ mod internal {
|
||||||
// Don't allow synchronous borrows to cut in line; if there are any
|
// Don't allow synchronous borrows to cut in line; if there are any
|
||||||
// enqueued waiters, return `None`, even if the current borrow is a shared
|
// enqueued waiters, return `None`, even if the current borrow is a shared
|
||||||
// one and the requested borrow is too.
|
// one and the requested borrow is too.
|
||||||
|
// TODO(piscisaureus): safety comment
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
let waiters = unsafe { &mut *cell_ref.waiters.as_ptr() };
|
let waiters = unsafe { &mut *cell_ref.waiters.as_ptr() };
|
||||||
if waiters.is_empty() {
|
if waiters.is_empty() {
|
||||||
// There are no enqueued waiters, but it is still possible that the cell
|
// There are no enqueued waiters, but it is still possible that the cell
|
||||||
|
@ -288,6 +298,8 @@ mod internal {
|
||||||
let waiter = Waiter::new(M::borrow_mode());
|
let waiter = Waiter::new(M::borrow_mode());
|
||||||
let turn = self.turn.get();
|
let turn = self.turn.get();
|
||||||
let index = {
|
let index = {
|
||||||
|
// TODO(piscisaureus): safety comment
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
let waiters = unsafe { &mut *self.waiters.as_ptr() };
|
let waiters = unsafe { &mut *self.waiters.as_ptr() };
|
||||||
waiters.push_back(Some(waiter));
|
waiters.push_back(Some(waiter));
|
||||||
waiters.len() - 1
|
waiters.len() - 1
|
||||||
|
@ -315,6 +327,8 @@ mod internal {
|
||||||
Poll::Ready(())
|
Poll::Ready(())
|
||||||
} else {
|
} else {
|
||||||
// This waiter is still in line and has not yet been woken.
|
// This waiter is still in line and has not yet been woken.
|
||||||
|
// TODO(piscisaureus): safety comment
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
let waiters = unsafe { &mut *self.waiters.as_ptr() };
|
let waiters = unsafe { &mut *self.waiters.as_ptr() };
|
||||||
// Sanity check: id cannot be higher than the last queue element.
|
// Sanity check: id cannot be higher than the last queue element.
|
||||||
assert!(id < turn + waiters.len());
|
assert!(id < turn + waiters.len());
|
||||||
|
@ -330,6 +344,8 @@ mod internal {
|
||||||
|
|
||||||
fn wake_waiters(&self) {
|
fn wake_waiters(&self) {
|
||||||
let mut borrow_count = self.borrow_count.get();
|
let mut borrow_count = self.borrow_count.get();
|
||||||
|
// TODO(piscisaureus): safety comment
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
let waiters = unsafe { &mut *self.waiters.as_ptr() };
|
let waiters = unsafe { &mut *self.waiters.as_ptr() };
|
||||||
let mut turn = self.turn.get();
|
let mut turn = self.turn.get();
|
||||||
|
|
||||||
|
@ -379,6 +395,8 @@ mod internal {
|
||||||
self.drop_borrow::<M>();
|
self.drop_borrow::<M>();
|
||||||
} else {
|
} else {
|
||||||
// This waiter is still in the queue, take it out and leave a "hole".
|
// This waiter is still in the queue, take it out and leave a "hole".
|
||||||
|
// TODO(piscisaureus): safety comment
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
let waiters = unsafe { &mut *self.waiters.as_ptr() };
|
let waiters = unsafe { &mut *self.waiters.as_ptr() };
|
||||||
waiters[id - turn].take().unwrap();
|
waiters[id - turn].take().unwrap();
|
||||||
}
|
}
|
||||||
|
@ -411,6 +429,8 @@ mod internal {
|
||||||
type Output = AsyncBorrowImpl<T, M>;
|
type Output = AsyncBorrowImpl<T, M>;
|
||||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
ready!(self.cell.as_ref().unwrap().poll_waiter::<M>(self.id, cx));
|
ready!(self.cell.as_ref().unwrap().poll_waiter::<M>(self.id, cx));
|
||||||
|
// TODO(piscisaureus): safety comment
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
let self_mut = unsafe { Pin::get_unchecked_mut(self) };
|
let self_mut = unsafe { Pin::get_unchecked_mut(self) };
|
||||||
let cell = self_mut.cell.take().unwrap();
|
let cell = self_mut.cell.take().unwrap();
|
||||||
Poll::Ready(AsyncBorrowImpl::<T, M>::new(cell))
|
Poll::Ready(AsyncBorrowImpl::<T, M>::new(cell))
|
||||||
|
@ -448,7 +468,11 @@ mod internal {
|
||||||
impl<T, M: BorrowModeTrait> Deref for AsyncBorrowImpl<T, M> {
|
impl<T, M: BorrowModeTrait> Deref for AsyncBorrowImpl<T, M> {
|
||||||
type Target = T;
|
type Target = T;
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
unsafe { &*self.cell.as_ptr() }
|
// TODO(piscisaureus): safety comment
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
|
unsafe {
|
||||||
|
&*self.cell.as_ptr()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -466,7 +490,11 @@ mod internal {
|
||||||
|
|
||||||
impl<T> DerefMut for AsyncBorrowImpl<T, Exclusive> {
|
impl<T> DerefMut for AsyncBorrowImpl<T, Exclusive> {
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
unsafe { &mut *self.cell.as_ptr() }
|
// TODO(piscisaureus): safety comment
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
|
unsafe {
|
||||||
|
&mut *self.cell.as_ptr()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -147,6 +147,7 @@ pub extern "C" fn host_import_module_dynamically_callback(
|
||||||
specifier: v8::Local<v8::String>,
|
specifier: v8::Local<v8::String>,
|
||||||
import_assertions: v8::Local<v8::FixedArray>,
|
import_assertions: v8::Local<v8::FixedArray>,
|
||||||
) -> *mut v8::Promise {
|
) -> *mut v8::Promise {
|
||||||
|
// SAFETY: `CallbackScope` can be safely constructed from `Local<Context>`
|
||||||
let scope = &mut unsafe { v8::CallbackScope::new(context) };
|
let scope = &mut unsafe { v8::CallbackScope::new(context) };
|
||||||
|
|
||||||
// NOTE(bartlomieju): will crash for non-UTF-8 specifier
|
// NOTE(bartlomieju): will crash for non-UTF-8 specifier
|
||||||
|
@ -253,6 +254,7 @@ pub extern "C" fn host_initialize_import_meta_object_callback(
|
||||||
module: v8::Local<v8::Module>,
|
module: v8::Local<v8::Module>,
|
||||||
meta: v8::Local<v8::Object>,
|
meta: v8::Local<v8::Object>,
|
||||||
) {
|
) {
|
||||||
|
// SAFETY: `CallbackScope` can be safely constructed from `Local<Context>`
|
||||||
let scope = &mut unsafe { v8::CallbackScope::new(context) };
|
let scope = &mut unsafe { v8::CallbackScope::new(context) };
|
||||||
let module_map_rc = JsRuntime::module_map(scope);
|
let module_map_rc = JsRuntime::module_map(scope);
|
||||||
let module_map = module_map_rc.borrow();
|
let module_map = module_map_rc.borrow();
|
||||||
|
@ -274,6 +276,7 @@ pub extern "C" fn host_initialize_import_meta_object_callback(
|
||||||
pub extern "C" fn promise_reject_callback(message: v8::PromiseRejectMessage) {
|
pub extern "C" fn promise_reject_callback(message: v8::PromiseRejectMessage) {
|
||||||
use v8::PromiseRejectEvent::*;
|
use v8::PromiseRejectEvent::*;
|
||||||
|
|
||||||
|
// SAFETY: `CallbackScope` can be safely constructed from `&PromiseRejectMessage`
|
||||||
let scope = &mut unsafe { v8::CallbackScope::new(&message) };
|
let scope = &mut unsafe { v8::CallbackScope::new(&message) };
|
||||||
|
|
||||||
let state_rc = JsRuntime::state(scope);
|
let state_rc = JsRuntime::state(scope);
|
||||||
|
@ -418,6 +421,7 @@ pub fn module_resolve_callback<'s>(
|
||||||
import_assertions: v8::Local<'s, v8::FixedArray>,
|
import_assertions: v8::Local<'s, v8::FixedArray>,
|
||||||
referrer: v8::Local<'s, v8::Module>,
|
referrer: v8::Local<'s, v8::Module>,
|
||||||
) -> Option<v8::Local<'s, v8::Module>> {
|
) -> Option<v8::Local<'s, v8::Module>> {
|
||||||
|
// SAFETY: `CallbackScope` can be safely constructed from `Local<Context>`
|
||||||
let scope = &mut unsafe { v8::CallbackScope::new(context) };
|
let scope = &mut unsafe { v8::CallbackScope::new(context) };
|
||||||
|
|
||||||
let module_map_rc = JsRuntime::module_map(scope);
|
let module_map_rc = JsRuntime::module_map(scope);
|
||||||
|
|
|
@ -485,6 +485,8 @@ impl task::ArcWake for InspectorWaker {
|
||||||
_isolate: &mut v8::Isolate,
|
_isolate: &mut v8::Isolate,
|
||||||
arg: *mut c_void,
|
arg: *mut c_void,
|
||||||
) {
|
) {
|
||||||
|
// SAFETY: `InspectorWaker` is owned by `JsRuntimeInspector`, so the
|
||||||
|
// pointer to the latter is valid as long as waker is alive.
|
||||||
let inspector = unsafe { &*(arg as *mut JsRuntimeInspector) };
|
let inspector = unsafe { &*(arg as *mut JsRuntimeInspector) };
|
||||||
let _ = inspector.poll_sessions(None);
|
let _ = inspector.poll_sessions(None);
|
||||||
}
|
}
|
||||||
|
@ -521,6 +523,8 @@ impl InspectorSession {
|
||||||
let v8_channel = v8::inspector::ChannelBase::new::<Self>();
|
let v8_channel = v8::inspector::ChannelBase::new::<Self>();
|
||||||
let mut v8_inspector = v8_inspector_rc.borrow_mut();
|
let mut v8_inspector = v8_inspector_rc.borrow_mut();
|
||||||
let v8_inspector_ptr = v8_inspector.as_mut().unwrap();
|
let v8_inspector_ptr = v8_inspector.as_mut().unwrap();
|
||||||
|
// TODO(piscisaureus): safety comment
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
let v8_session = v8_inspector_ptr.connect(
|
let v8_session = v8_inspector_ptr.connect(
|
||||||
Self::CONTEXT_GROUP_ID,
|
Self::CONTEXT_GROUP_ID,
|
||||||
// Todo(piscisaureus): V8Inspector::connect() should require that
|
// Todo(piscisaureus): V8Inspector::connect() should require that
|
||||||
|
@ -544,6 +548,8 @@ impl InspectorSession {
|
||||||
msg: String,
|
msg: String,
|
||||||
) {
|
) {
|
||||||
let msg = v8::inspector::StringView::from(msg.as_bytes());
|
let msg = v8::inspector::StringView::from(msg.as_bytes());
|
||||||
|
// SAFETY: `InspectorSession` is the only owner of `v8_session_ptr`, so
|
||||||
|
// the pointer is valid for as long the struct.
|
||||||
unsafe {
|
unsafe {
|
||||||
(*v8_session_ptr).dispatch_protocol_message(msg);
|
(*v8_session_ptr).dispatch_protocol_message(msg);
|
||||||
};
|
};
|
||||||
|
@ -731,6 +737,9 @@ impl LocalInspectorSession {
|
||||||
fn new_box_with<T>(new_fn: impl FnOnce(*mut T) -> T) -> Box<T> {
|
fn new_box_with<T>(new_fn: impl FnOnce(*mut T) -> T) -> Box<T> {
|
||||||
let b = Box::new(MaybeUninit::<T>::uninit());
|
let b = Box::new(MaybeUninit::<T>::uninit());
|
||||||
let p = Box::into_raw(b) as *mut T;
|
let p = Box::into_raw(b) as *mut T;
|
||||||
unsafe { ptr::write(p, new_fn(p)) };
|
// SAFETY: memory layout for `T` is ensured on first line of this function
|
||||||
unsafe { Box::from_raw(p) }
|
unsafe {
|
||||||
|
ptr::write(p, new_fn(p));
|
||||||
|
Box::from_raw(p)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,6 +122,7 @@ fn json_module_evaluation_steps<'a>(
|
||||||
context: v8::Local<'a, v8::Context>,
|
context: v8::Local<'a, v8::Context>,
|
||||||
module: v8::Local<v8::Module>,
|
module: v8::Local<v8::Module>,
|
||||||
) -> Option<v8::Local<'a, v8::Value>> {
|
) -> Option<v8::Local<'a, v8::Value>> {
|
||||||
|
// SAFETY: `CallbackScope` can be safely constructed from `Local<Context>`
|
||||||
let scope = &mut unsafe { v8::CallbackScope::new(context) };
|
let scope = &mut unsafe { v8::CallbackScope::new(context) };
|
||||||
let tc_scope = &mut v8::TryCatch::new(scope);
|
let tc_scope = &mut v8::TryCatch::new(scope);
|
||||||
let module_map = tc_scope
|
let module_map = tc_scope
|
||||||
|
|
|
@ -63,6 +63,8 @@ impl<T> Future for OpCall<T> {
|
||||||
self: std::pin::Pin<&mut Self>,
|
self: std::pin::Pin<&mut Self>,
|
||||||
cx: &mut std::task::Context<'_>,
|
cx: &mut std::task::Context<'_>,
|
||||||
) -> std::task::Poll<Self::Output> {
|
) -> std::task::Poll<Self::Output> {
|
||||||
|
// TODO(piscisaureus): safety comment
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
let inner = unsafe { &mut self.get_unchecked_mut().0 };
|
let inner = unsafe { &mut self.get_unchecked_mut().0 };
|
||||||
let mut pinned = Pin::new(inner);
|
let mut pinned = Pin::new(inner);
|
||||||
ready!(pinned.as_mut().poll(cx));
|
ready!(pinned.as_mut().poll(cx));
|
||||||
|
|
|
@ -56,12 +56,17 @@ impl OpsTracker {
|
||||||
#[allow(clippy::mut_from_ref)]
|
#[allow(clippy::mut_from_ref)]
|
||||||
#[inline]
|
#[inline]
|
||||||
fn ops_mut(&self) -> &mut Vec<OpMetrics> {
|
fn ops_mut(&self) -> &mut Vec<OpMetrics> {
|
||||||
|
// SAFETY: `OpsTracker` is created after registering ops so it is guaranteed
|
||||||
|
// that that `ops` will be initialized.
|
||||||
unsafe { &mut *self.ops.get() }
|
unsafe { &mut *self.ops.get() }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::mut_from_ref)]
|
#[allow(clippy::mut_from_ref)]
|
||||||
#[inline]
|
#[inline]
|
||||||
fn metrics_mut(&self, id: OpId) -> &mut OpMetrics {
|
fn metrics_mut(&self, id: OpId) -> &mut OpMetrics {
|
||||||
|
// SAFETY: `OpsTracker` is created after registering ops, and ops
|
||||||
|
// cannot be unregistered during runtime, so it is guaranteed that `id`
|
||||||
|
// is not causing out-of-bound access.
|
||||||
unsafe { self.ops_mut().get_unchecked_mut(id) }
|
unsafe { self.ops_mut().get_unchecked_mut(id) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,6 +77,8 @@ impl dyn Resource {
|
||||||
pub fn downcast_rc<'a, T: Resource>(self: &'a Rc<Self>) -> Option<&'a Rc<T>> {
|
pub fn downcast_rc<'a, T: Resource>(self: &'a Rc<Self>) -> Option<&'a Rc<T>> {
|
||||||
if self.is::<T>() {
|
if self.is::<T>() {
|
||||||
let ptr = self as *const Rc<_> as *const Rc<T>;
|
let ptr = self as *const Rc<_> as *const Rc<T>;
|
||||||
|
// TODO(piscisaureus): safety comment
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
Some(unsafe { &*ptr })
|
Some(unsafe { &*ptr })
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
@ -333,6 +333,9 @@ impl JsRuntime {
|
||||||
assert!(options.startup_snapshot.is_none());
|
assert!(options.startup_snapshot.is_none());
|
||||||
let mut creator =
|
let mut creator =
|
||||||
v8::SnapshotCreator::new(Some(&bindings::EXTERNAL_REFERENCES));
|
v8::SnapshotCreator::new(Some(&bindings::EXTERNAL_REFERENCES));
|
||||||
|
// SAFETY: `get_owned_isolate` is unsafe because it may only be called
|
||||||
|
// once. This is the only place we call this function, so this call is
|
||||||
|
// safe.
|
||||||
let isolate = unsafe { creator.get_owned_isolate() };
|
let isolate = unsafe { creator.get_owned_isolate() };
|
||||||
let mut isolate = JsRuntime::setup_isolate(isolate);
|
let mut isolate = JsRuntime::setup_isolate(isolate);
|
||||||
{
|
{
|
||||||
|
@ -1028,6 +1031,8 @@ extern "C" fn near_heap_limit_callback<F>(
|
||||||
where
|
where
|
||||||
F: FnMut(usize, usize) -> usize,
|
F: FnMut(usize, usize) -> usize,
|
||||||
{
|
{
|
||||||
|
// SAFETY: The data is a pointer to the Rust callback function. It is stored
|
||||||
|
// in `JsRuntime::allocations` and thus is guaranteed to outlive the isolate.
|
||||||
let callback = unsafe { &mut *(data as *mut F) };
|
let callback = unsafe { &mut *(data as *mut F) };
|
||||||
callback(current_heap_limit, initial_heap_limit)
|
callback(current_heap_limit, initial_heap_limit)
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,6 +130,8 @@ impl DynamicLibraryResource {
|
||||||
// By default, Err returned by this function does not tell
|
// By default, Err returned by this function does not tell
|
||||||
// which symbol wasn't exported. So we'll modify the error
|
// which symbol wasn't exported. So we'll modify the error
|
||||||
// message to include the name of symbol.
|
// message to include the name of symbol.
|
||||||
|
//
|
||||||
|
// SAFETY: The obtained T symbol is the size of a pointer.
|
||||||
let fn_ptr = match unsafe { self.lib.symbol::<*const c_void>(symbol) } {
|
let fn_ptr = match unsafe { self.lib.symbol::<*const c_void>(symbol) } {
|
||||||
Ok(value) => Ok(value),
|
Ok(value) => Ok(value),
|
||||||
Err(err) => Err(generic_error(format!(
|
Err(err) => Err(generic_error(format!(
|
||||||
|
@ -164,6 +166,8 @@ impl DynamicLibraryResource {
|
||||||
// By default, Err returned by this function does not tell
|
// By default, Err returned by this function does not tell
|
||||||
// which symbol wasn't exported. So we'll modify the error
|
// which symbol wasn't exported. So we'll modify the error
|
||||||
// message to include the name of symbol.
|
// message to include the name of symbol.
|
||||||
|
//
|
||||||
|
// SAFETY: The obtained T symbol is the size of a pointer.
|
||||||
match unsafe { self.lib.symbol::<*const c_void>(&symbol) } {
|
match unsafe { self.lib.symbol::<*const c_void>(&symbol) } {
|
||||||
Ok(value) => Ok(Ok(value)),
|
Ok(value) => Ok(Ok(value)),
|
||||||
Err(err) => Err(generic_error(format!(
|
Err(err) => Err(generic_error(format!(
|
||||||
|
@ -743,55 +747,60 @@ fn ffi_call(
|
||||||
let call_args: Vec<Arg> = call_args
|
let call_args: Vec<Arg> = call_args
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(index, ffi_arg)| unsafe {
|
.map(|(index, ffi_arg)| {
|
||||||
ffi_arg.as_arg(*parameter_types.get(index).unwrap())
|
// SAFETY: the union field is initialized
|
||||||
|
unsafe { ffi_arg.as_arg(*parameter_types.get(index).unwrap()) }
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
// SAFETY: types in the `Cif` match the actual calling convention and
|
||||||
|
// types of symbol.
|
||||||
|
unsafe {
|
||||||
Ok(match result_type {
|
Ok(match result_type {
|
||||||
NativeType::Void => NativeValue {
|
NativeType::Void => NativeValue {
|
||||||
void_value: unsafe { cif.call::<()>(fun_ptr, &call_args) },
|
void_value: cif.call::<()>(fun_ptr, &call_args),
|
||||||
},
|
},
|
||||||
NativeType::U8 => NativeValue {
|
NativeType::U8 => NativeValue {
|
||||||
u8_value: unsafe { cif.call::<u8>(fun_ptr, &call_args) },
|
u8_value: cif.call::<u8>(fun_ptr, &call_args),
|
||||||
},
|
},
|
||||||
NativeType::I8 => NativeValue {
|
NativeType::I8 => NativeValue {
|
||||||
i8_value: unsafe { cif.call::<i8>(fun_ptr, &call_args) },
|
i8_value: cif.call::<i8>(fun_ptr, &call_args),
|
||||||
},
|
},
|
||||||
NativeType::U16 => NativeValue {
|
NativeType::U16 => NativeValue {
|
||||||
u16_value: unsafe { cif.call::<u16>(fun_ptr, &call_args) },
|
u16_value: cif.call::<u16>(fun_ptr, &call_args),
|
||||||
},
|
},
|
||||||
NativeType::I16 => NativeValue {
|
NativeType::I16 => NativeValue {
|
||||||
i16_value: unsafe { cif.call::<i16>(fun_ptr, &call_args) },
|
i16_value: cif.call::<i16>(fun_ptr, &call_args),
|
||||||
},
|
},
|
||||||
NativeType::U32 => NativeValue {
|
NativeType::U32 => NativeValue {
|
||||||
u32_value: unsafe { cif.call::<u32>(fun_ptr, &call_args) },
|
u32_value: cif.call::<u32>(fun_ptr, &call_args),
|
||||||
},
|
},
|
||||||
NativeType::I32 => NativeValue {
|
NativeType::I32 => NativeValue {
|
||||||
i32_value: unsafe { cif.call::<i32>(fun_ptr, &call_args) },
|
i32_value: cif.call::<i32>(fun_ptr, &call_args),
|
||||||
},
|
},
|
||||||
NativeType::U64 => NativeValue {
|
NativeType::U64 => NativeValue {
|
||||||
u64_value: unsafe { cif.call::<u64>(fun_ptr, &call_args) },
|
u64_value: cif.call::<u64>(fun_ptr, &call_args),
|
||||||
},
|
},
|
||||||
NativeType::I64 => NativeValue {
|
NativeType::I64 => NativeValue {
|
||||||
i64_value: unsafe { cif.call::<i64>(fun_ptr, &call_args) },
|
i64_value: cif.call::<i64>(fun_ptr, &call_args),
|
||||||
},
|
},
|
||||||
NativeType::USize => NativeValue {
|
NativeType::USize => NativeValue {
|
||||||
usize_value: unsafe { cif.call::<usize>(fun_ptr, &call_args) },
|
usize_value: cif.call::<usize>(fun_ptr, &call_args),
|
||||||
},
|
},
|
||||||
NativeType::ISize => NativeValue {
|
NativeType::ISize => NativeValue {
|
||||||
isize_value: unsafe { cif.call::<isize>(fun_ptr, &call_args) },
|
isize_value: cif.call::<isize>(fun_ptr, &call_args),
|
||||||
},
|
},
|
||||||
NativeType::F32 => NativeValue {
|
NativeType::F32 => NativeValue {
|
||||||
f32_value: unsafe { cif.call::<f32>(fun_ptr, &call_args) },
|
f32_value: cif.call::<f32>(fun_ptr, &call_args),
|
||||||
},
|
},
|
||||||
NativeType::F64 => NativeValue {
|
NativeType::F64 => NativeValue {
|
||||||
f64_value: unsafe { cif.call::<f64>(fun_ptr, &call_args) },
|
f64_value: cif.call::<f64>(fun_ptr, &call_args),
|
||||||
},
|
},
|
||||||
NativeType::Pointer | NativeType::Function => NativeValue {
|
NativeType::Pointer | NativeType::Function => NativeValue {
|
||||||
pointer: unsafe { cif.call::<*const u8>(fun_ptr, &call_args) },
|
pointer: cif.call::<*const u8>(fun_ptr, &call_args),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct UnsafeCallbackResource {
|
struct UnsafeCallbackResource {
|
||||||
|
@ -1201,71 +1210,83 @@ fn op_ffi_get_static<'scope>(
|
||||||
return Err(type_error("Invalid FFI static type 'void'"));
|
return Err(type_error("Invalid FFI static type 'void'"));
|
||||||
}
|
}
|
||||||
NativeType::U8 => {
|
NativeType::U8 => {
|
||||||
|
// SAFETY: ptr is user provided
|
||||||
let result = unsafe { ptr::read_unaligned(data_ptr as *const u8) };
|
let result = unsafe { ptr::read_unaligned(data_ptr as *const u8) };
|
||||||
let number: v8::Local<v8::Value> =
|
let number: v8::Local<v8::Value> =
|
||||||
v8::Integer::new_from_unsigned(scope, result as u32).into();
|
v8::Integer::new_from_unsigned(scope, result as u32).into();
|
||||||
number.into()
|
number.into()
|
||||||
}
|
}
|
||||||
NativeType::I8 => {
|
NativeType::I8 => {
|
||||||
|
// SAFETY: ptr is user provided
|
||||||
let result = unsafe { ptr::read_unaligned(data_ptr as *const i8) };
|
let result = unsafe { ptr::read_unaligned(data_ptr as *const i8) };
|
||||||
let number: v8::Local<v8::Value> =
|
let number: v8::Local<v8::Value> =
|
||||||
v8::Integer::new(scope, result as i32).into();
|
v8::Integer::new(scope, result as i32).into();
|
||||||
number.into()
|
number.into()
|
||||||
}
|
}
|
||||||
NativeType::U16 => {
|
NativeType::U16 => {
|
||||||
|
// SAFETY: ptr is user provided
|
||||||
let result = unsafe { ptr::read_unaligned(data_ptr as *const u16) };
|
let result = unsafe { ptr::read_unaligned(data_ptr as *const u16) };
|
||||||
let number: v8::Local<v8::Value> =
|
let number: v8::Local<v8::Value> =
|
||||||
v8::Integer::new_from_unsigned(scope, result as u32).into();
|
v8::Integer::new_from_unsigned(scope, result as u32).into();
|
||||||
number.into()
|
number.into()
|
||||||
}
|
}
|
||||||
NativeType::I16 => {
|
NativeType::I16 => {
|
||||||
|
// SAFETY: ptr is user provided
|
||||||
let result = unsafe { ptr::read_unaligned(data_ptr as *const i16) };
|
let result = unsafe { ptr::read_unaligned(data_ptr as *const i16) };
|
||||||
let number: v8::Local<v8::Value> =
|
let number: v8::Local<v8::Value> =
|
||||||
v8::Integer::new(scope, result as i32).into();
|
v8::Integer::new(scope, result as i32).into();
|
||||||
number.into()
|
number.into()
|
||||||
}
|
}
|
||||||
NativeType::U32 => {
|
NativeType::U32 => {
|
||||||
|
// SAFETY: ptr is user provided
|
||||||
let result = unsafe { ptr::read_unaligned(data_ptr as *const u32) };
|
let result = unsafe { ptr::read_unaligned(data_ptr as *const u32) };
|
||||||
let number: v8::Local<v8::Value> =
|
let number: v8::Local<v8::Value> =
|
||||||
v8::Integer::new_from_unsigned(scope, result).into();
|
v8::Integer::new_from_unsigned(scope, result).into();
|
||||||
number.into()
|
number.into()
|
||||||
}
|
}
|
||||||
NativeType::I32 => {
|
NativeType::I32 => {
|
||||||
|
// SAFETY: ptr is user provided
|
||||||
let result = unsafe { ptr::read_unaligned(data_ptr as *const i32) };
|
let result = unsafe { ptr::read_unaligned(data_ptr as *const i32) };
|
||||||
let number: v8::Local<v8::Value> = v8::Integer::new(scope, result).into();
|
let number: v8::Local<v8::Value> = v8::Integer::new(scope, result).into();
|
||||||
number.into()
|
number.into()
|
||||||
}
|
}
|
||||||
NativeType::U64 => {
|
NativeType::U64 => {
|
||||||
|
// SAFETY: ptr is user provided
|
||||||
let result = unsafe { ptr::read_unaligned(data_ptr as *const u64) };
|
let result = unsafe { ptr::read_unaligned(data_ptr as *const u64) };
|
||||||
let big_int: v8::Local<v8::Value> =
|
let big_int: v8::Local<v8::Value> =
|
||||||
v8::BigInt::new_from_u64(scope, result).into();
|
v8::BigInt::new_from_u64(scope, result).into();
|
||||||
big_int.into()
|
big_int.into()
|
||||||
}
|
}
|
||||||
NativeType::I64 => {
|
NativeType::I64 => {
|
||||||
|
// SAFETY: ptr is user provided
|
||||||
let result = unsafe { ptr::read_unaligned(data_ptr as *const i64) };
|
let result = unsafe { ptr::read_unaligned(data_ptr as *const i64) };
|
||||||
let big_int: v8::Local<v8::Value> =
|
let big_int: v8::Local<v8::Value> =
|
||||||
v8::BigInt::new_from_i64(scope, result).into();
|
v8::BigInt::new_from_i64(scope, result).into();
|
||||||
big_int.into()
|
big_int.into()
|
||||||
}
|
}
|
||||||
NativeType::USize => {
|
NativeType::USize => {
|
||||||
|
// SAFETY: ptr is user provided
|
||||||
let result = unsafe { ptr::read_unaligned(data_ptr as *const usize) };
|
let result = unsafe { ptr::read_unaligned(data_ptr as *const usize) };
|
||||||
let big_int: v8::Local<v8::Value> =
|
let big_int: v8::Local<v8::Value> =
|
||||||
v8::BigInt::new_from_u64(scope, result as u64).into();
|
v8::BigInt::new_from_u64(scope, result as u64).into();
|
||||||
big_int.into()
|
big_int.into()
|
||||||
}
|
}
|
||||||
NativeType::ISize => {
|
NativeType::ISize => {
|
||||||
|
// SAFETY: ptr is user provided
|
||||||
let result = unsafe { ptr::read_unaligned(data_ptr as *const isize) };
|
let result = unsafe { ptr::read_unaligned(data_ptr as *const isize) };
|
||||||
let big_int: v8::Local<v8::Value> =
|
let big_int: v8::Local<v8::Value> =
|
||||||
v8::BigInt::new_from_i64(scope, result as i64).into();
|
v8::BigInt::new_from_i64(scope, result as i64).into();
|
||||||
big_int.into()
|
big_int.into()
|
||||||
}
|
}
|
||||||
NativeType::F32 => {
|
NativeType::F32 => {
|
||||||
|
// SAFETY: ptr is user provided
|
||||||
let result = unsafe { ptr::read_unaligned(data_ptr as *const f32) };
|
let result = unsafe { ptr::read_unaligned(data_ptr as *const f32) };
|
||||||
let number: v8::Local<v8::Value> =
|
let number: v8::Local<v8::Value> =
|
||||||
v8::Number::new(scope, result as f64).into();
|
v8::Number::new(scope, result as f64).into();
|
||||||
number.into()
|
number.into()
|
||||||
}
|
}
|
||||||
NativeType::F64 => {
|
NativeType::F64 => {
|
||||||
|
// SAFETY: ptr is user provided
|
||||||
let result = unsafe { ptr::read_unaligned(data_ptr as *const f64) };
|
let result = unsafe { ptr::read_unaligned(data_ptr as *const f64) };
|
||||||
let number: v8::Local<v8::Value> = v8::Number::new(scope, result).into();
|
let number: v8::Local<v8::Value> = v8::Number::new(scope, result).into();
|
||||||
number.into()
|
number.into()
|
||||||
|
@ -1339,7 +1360,7 @@ fn op_ffi_call_nonblocking<'scope>(
|
||||||
cif,
|
cif,
|
||||||
ptr,
|
ptr,
|
||||||
parameter_types,
|
parameter_types,
|
||||||
..
|
result_type,
|
||||||
} = symbol.clone();
|
} = symbol.clone();
|
||||||
ffi_call(call_args, &cif, ptr, ¶meter_types, result_type)
|
ffi_call(call_args, &cif, ptr, ¶meter_types, result_type)
|
||||||
});
|
});
|
||||||
|
@ -1392,6 +1413,8 @@ where
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
let src = src as *const u8;
|
let src = src as *const u8;
|
||||||
|
// SAFETY: src is user defined.
|
||||||
|
// dest is properly aligned and is valid for writes of len * size_of::<T>() bytes.
|
||||||
unsafe { ptr::copy(src, dst.as_mut_ptr(), len) };
|
unsafe { ptr::copy(src, dst.as_mut_ptr(), len) };
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1411,6 +1434,8 @@ where
|
||||||
permissions.check(None)?;
|
permissions.check(None)?;
|
||||||
|
|
||||||
let ptr = ptr as *const c_char;
|
let ptr = ptr as *const c_char;
|
||||||
|
// SAFETY: ptr is user provided
|
||||||
|
// lifetime validity is not an issue because we allocate a new string.
|
||||||
Ok(unsafe { CStr::from_ptr(ptr) }.to_str()?.to_string())
|
Ok(unsafe { CStr::from_ptr(ptr) }.to_str()?.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1427,6 +1452,7 @@ where
|
||||||
let permissions = state.borrow_mut::<FP>();
|
let permissions = state.borrow_mut::<FP>();
|
||||||
permissions.check(None)?;
|
permissions.check(None)?;
|
||||||
|
|
||||||
|
// SAFETY: ptr is user provided.
|
||||||
Ok(unsafe { ptr::read_unaligned(ptr as *const u8) })
|
Ok(unsafe { ptr::read_unaligned(ptr as *const u8) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1443,6 +1469,7 @@ where
|
||||||
let permissions = state.borrow_mut::<FP>();
|
let permissions = state.borrow_mut::<FP>();
|
||||||
permissions.check(None)?;
|
permissions.check(None)?;
|
||||||
|
|
||||||
|
// SAFETY: ptr is user provided.
|
||||||
Ok(unsafe { ptr::read_unaligned(ptr as *const i8) })
|
Ok(unsafe { ptr::read_unaligned(ptr as *const i8) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1459,6 +1486,7 @@ where
|
||||||
let permissions = state.borrow_mut::<FP>();
|
let permissions = state.borrow_mut::<FP>();
|
||||||
permissions.check(None)?;
|
permissions.check(None)?;
|
||||||
|
|
||||||
|
// SAFETY: ptr is user provided.
|
||||||
Ok(unsafe { ptr::read_unaligned(ptr as *const u16) })
|
Ok(unsafe { ptr::read_unaligned(ptr as *const u16) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1475,6 +1503,7 @@ where
|
||||||
let permissions = state.borrow_mut::<FP>();
|
let permissions = state.borrow_mut::<FP>();
|
||||||
permissions.check(None)?;
|
permissions.check(None)?;
|
||||||
|
|
||||||
|
// SAFETY: ptr is user provided.
|
||||||
Ok(unsafe { ptr::read_unaligned(ptr as *const i16) })
|
Ok(unsafe { ptr::read_unaligned(ptr as *const i16) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1491,6 +1520,7 @@ where
|
||||||
let permissions = state.borrow_mut::<FP>();
|
let permissions = state.borrow_mut::<FP>();
|
||||||
permissions.check(None)?;
|
permissions.check(None)?;
|
||||||
|
|
||||||
|
// SAFETY: ptr is user provided.
|
||||||
Ok(unsafe { ptr::read_unaligned(ptr as *const u32) })
|
Ok(unsafe { ptr::read_unaligned(ptr as *const u32) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1507,6 +1537,7 @@ where
|
||||||
let permissions = state.borrow_mut::<FP>();
|
let permissions = state.borrow_mut::<FP>();
|
||||||
permissions.check(None)?;
|
permissions.check(None)?;
|
||||||
|
|
||||||
|
// SAFETY: ptr is user provided.
|
||||||
Ok(unsafe { ptr::read_unaligned(ptr as *const i32) })
|
Ok(unsafe { ptr::read_unaligned(ptr as *const i32) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1525,6 +1556,7 @@ where
|
||||||
let permissions = state.borrow_mut::<FP>();
|
let permissions = state.borrow_mut::<FP>();
|
||||||
permissions.check(None)?;
|
permissions.check(None)?;
|
||||||
|
|
||||||
|
// SAFETY: ptr is user provided.
|
||||||
let result = unsafe { ptr::read_unaligned(ptr as *const u64) };
|
let result = unsafe { ptr::read_unaligned(ptr as *const u64) };
|
||||||
|
|
||||||
let big_int: v8::Local<v8::Value> =
|
let big_int: v8::Local<v8::Value> =
|
||||||
|
@ -1545,6 +1577,7 @@ where
|
||||||
let permissions = state.borrow_mut::<FP>();
|
let permissions = state.borrow_mut::<FP>();
|
||||||
permissions.check(None)?;
|
permissions.check(None)?;
|
||||||
|
|
||||||
|
// SAFETY: ptr is user provided.
|
||||||
Ok(unsafe { ptr::read_unaligned(ptr as *const f32) })
|
Ok(unsafe { ptr::read_unaligned(ptr as *const f32) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1561,6 +1594,7 @@ where
|
||||||
let permissions = state.borrow_mut::<FP>();
|
let permissions = state.borrow_mut::<FP>();
|
||||||
permissions.check(None)?;
|
permissions.check(None)?;
|
||||||
|
|
||||||
|
// SAFETY: ptr is user provided.
|
||||||
Ok(unsafe { ptr::read_unaligned(ptr as *const f64) })
|
Ok(unsafe { ptr::read_unaligned(ptr as *const f64) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -375,11 +375,17 @@ impl TlsStreamInner {
|
||||||
ready!(self.poll_io(cx, Flow::Read))?;
|
ready!(self.poll_io(cx, Flow::Read))?;
|
||||||
|
|
||||||
if self.rd_state == State::StreamOpen {
|
if self.rd_state == State::StreamOpen {
|
||||||
|
// TODO(bartlomieju):
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
let buf_slice =
|
let buf_slice =
|
||||||
unsafe { &mut *(buf.unfilled_mut() as *mut [_] as *mut [u8]) };
|
unsafe { &mut *(buf.unfilled_mut() as *mut [_] as *mut [u8]) };
|
||||||
let bytes_read = self.tls.reader().read(buf_slice)?;
|
let bytes_read = self.tls.reader().read(buf_slice)?;
|
||||||
assert_ne!(bytes_read, 0);
|
assert_ne!(bytes_read, 0);
|
||||||
unsafe { buf.assume_init(bytes_read) };
|
// TODO(bartlomieju):
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
|
unsafe {
|
||||||
|
buf.assume_init(bytes_read)
|
||||||
|
};
|
||||||
buf.advance(bytes_read);
|
buf.advance(bytes_read);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -581,10 +587,16 @@ impl Shared {
|
||||||
let self_weak = Arc::downgrade(self);
|
let self_weak = Arc::downgrade(self);
|
||||||
let self_ptr = self_weak.into_raw() as *const ();
|
let self_ptr = self_weak.into_raw() as *const ();
|
||||||
let raw_waker = RawWaker::new(self_ptr, &Self::SHARED_WAKER_VTABLE);
|
let raw_waker = RawWaker::new(self_ptr, &Self::SHARED_WAKER_VTABLE);
|
||||||
unsafe { Waker::from_raw(raw_waker) }
|
// TODO(bartlomieju):
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
|
unsafe {
|
||||||
|
Waker::from_raw(raw_waker)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clone_shared_waker(self_ptr: *const ()) -> RawWaker {
|
fn clone_shared_waker(self_ptr: *const ()) -> RawWaker {
|
||||||
|
// TODO(bartlomieju):
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
let self_weak = unsafe { Weak::from_raw(self_ptr as *const Self) };
|
let self_weak = unsafe { Weak::from_raw(self_ptr as *const Self) };
|
||||||
let ptr1 = self_weak.clone().into_raw();
|
let ptr1 = self_weak.clone().into_raw();
|
||||||
let ptr2 = self_weak.into_raw();
|
let ptr2 = self_weak.into_raw();
|
||||||
|
@ -598,6 +610,8 @@ impl Shared {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wake_shared_waker_by_ref(self_ptr: *const ()) {
|
fn wake_shared_waker_by_ref(self_ptr: *const ()) {
|
||||||
|
// TODO(bartlomieju):
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
let self_weak = unsafe { Weak::from_raw(self_ptr as *const Self) };
|
let self_weak = unsafe { Weak::from_raw(self_ptr as *const Self) };
|
||||||
if let Some(self_arc) = Weak::upgrade(&self_weak) {
|
if let Some(self_arc) = Weak::upgrade(&self_weak) {
|
||||||
self_arc.rd_waker.wake();
|
self_arc.rd_waker.wake();
|
||||||
|
@ -607,6 +621,8 @@ impl Shared {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn drop_shared_waker(self_ptr: *const ()) {
|
fn drop_shared_waker(self_ptr: *const ()) {
|
||||||
|
// TODO(bartlomieju):
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
let _ = unsafe { Weak::from_raw(self_ptr as *const Self) };
|
let _ = unsafe { Weak::from_raw(self_ptr as *const Self) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,6 +105,8 @@ pub async fn op_webgpu_buffer_get_map_async(
|
||||||
user_data: *mut u8,
|
user_data: *mut u8,
|
||||||
) {
|
) {
|
||||||
let sender_ptr = user_data as *mut oneshot::Sender<Result<(), AnyError>>;
|
let sender_ptr = user_data as *mut oneshot::Sender<Result<(), AnyError>>;
|
||||||
|
// TODO(bartlomieju):
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
let boxed_sender = unsafe { Box::from_raw(sender_ptr) };
|
let boxed_sender = unsafe { Box::from_raw(sender_ptr) };
|
||||||
boxed_sender
|
boxed_sender
|
||||||
.send(match status {
|
.send(match status {
|
||||||
|
@ -188,6 +190,8 @@ pub fn op_webgpu_buffer_get_mapped_range(
|
||||||
))
|
))
|
||||||
.map_err(|e| DomExceptionOperationError::new(&e.to_string()))?;
|
.map_err(|e| DomExceptionOperationError::new(&e.to_string()))?;
|
||||||
|
|
||||||
|
// TODO(bartlomieju):
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
let slice = unsafe {
|
let slice = unsafe {
|
||||||
std::slice::from_raw_parts_mut(slice_pointer, range_size as usize)
|
std::slice::from_raw_parts_mut(slice_pointer, range_size as usize)
|
||||||
};
|
};
|
||||||
|
@ -225,6 +229,8 @@ pub fn op_webgpu_buffer_unmap(
|
||||||
let size = mapped_resource.1;
|
let size = mapped_resource.1;
|
||||||
|
|
||||||
if let Some(buffer) = zero_copy {
|
if let Some(buffer) = zero_copy {
|
||||||
|
// TODO(bartlomieju):
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
let slice = unsafe { std::slice::from_raw_parts_mut(slice_pointer, size) };
|
let slice = unsafe { std::slice::from_raw_parts_mut(slice_pointer, size) };
|
||||||
slice.copy_from_slice(&buffer);
|
slice.copy_from_slice(&buffer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,26 +42,35 @@ use {
|
||||||
// alive for the duration of the application since the last handle/fd
|
// alive for the duration of the application since the last handle/fd
|
||||||
// being dropped will close the corresponding pipe.
|
// being dropped will close the corresponding pipe.
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
static STDIN_HANDLE: Lazy<StdFile> =
|
static STDIN_HANDLE: Lazy<StdFile> = Lazy::new(|| {
|
||||||
Lazy::new(|| unsafe { StdFile::from_raw_fd(0) });
|
// SAFETY: corresponds to OS stdin
|
||||||
|
unsafe { StdFile::from_raw_fd(0) }
|
||||||
|
});
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
static STDOUT_HANDLE: Lazy<StdFile> =
|
static STDOUT_HANDLE: Lazy<StdFile> = Lazy::new(|| {
|
||||||
Lazy::new(|| unsafe { StdFile::from_raw_fd(1) });
|
// SAFETY: corresponds to OS stdout
|
||||||
|
unsafe { StdFile::from_raw_fd(1) }
|
||||||
|
});
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
static STDERR_HANDLE: Lazy<StdFile> =
|
static STDERR_HANDLE: Lazy<StdFile> = Lazy::new(|| {
|
||||||
Lazy::new(|| unsafe { StdFile::from_raw_fd(2) });
|
// SAFETY: corresponds to OS stderr
|
||||||
|
unsafe { StdFile::from_raw_fd(2) }
|
||||||
|
});
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
static STDIN_HANDLE: Lazy<StdFile> = Lazy::new(|| unsafe {
|
static STDIN_HANDLE: Lazy<StdFile> = Lazy::new(|| {
|
||||||
StdFile::from_raw_handle(GetStdHandle(winbase::STD_INPUT_HANDLE))
|
// SAFETY: corresponds to OS stdin
|
||||||
|
unsafe { StdFile::from_raw_handle(GetStdHandle(winbase::STD_INPUT_HANDLE)) }
|
||||||
});
|
});
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
static STDOUT_HANDLE: Lazy<StdFile> = Lazy::new(|| unsafe {
|
static STDOUT_HANDLE: Lazy<StdFile> = Lazy::new(|| {
|
||||||
StdFile::from_raw_handle(GetStdHandle(winbase::STD_OUTPUT_HANDLE))
|
// SAFETY: corresponds to OS stdout
|
||||||
|
unsafe { StdFile::from_raw_handle(GetStdHandle(winbase::STD_OUTPUT_HANDLE)) }
|
||||||
});
|
});
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
static STDERR_HANDLE: Lazy<StdFile> = Lazy::new(|| unsafe {
|
static STDERR_HANDLE: Lazy<StdFile> = Lazy::new(|| {
|
||||||
StdFile::from_raw_handle(GetStdHandle(winbase::STD_ERROR_HANDLE))
|
// SAFETY: corresponds to OS stderr
|
||||||
|
unsafe { StdFile::from_raw_handle(GetStdHandle(winbase::STD_ERROR_HANDLE)) }
|
||||||
});
|
});
|
||||||
|
|
||||||
pub fn init() -> Extension {
|
pub fn init() -> Extension {
|
||||||
|
|
|
@ -248,7 +248,11 @@ fn op_system_memory_info(
|
||||||
fn op_getgid(state: &mut OpState) -> Result<Option<u32>, AnyError> {
|
fn op_getgid(state: &mut OpState) -> Result<Option<u32>, AnyError> {
|
||||||
super::check_unstable(state, "Deno.getGid");
|
super::check_unstable(state, "Deno.getGid");
|
||||||
state.borrow_mut::<Permissions>().env.check_all()?;
|
state.borrow_mut::<Permissions>().env.check_all()?;
|
||||||
unsafe { Ok(Some(libc::getgid())) }
|
// TODO(bartlomieju):
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
|
unsafe {
|
||||||
|
Ok(Some(libc::getgid()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
|
@ -264,7 +268,11 @@ fn op_getgid(state: &mut OpState) -> Result<Option<u32>, AnyError> {
|
||||||
fn op_getuid(state: &mut OpState) -> Result<Option<u32>, AnyError> {
|
fn op_getuid(state: &mut OpState) -> Result<Option<u32>, AnyError> {
|
||||||
super::check_unstable(state, "Deno.getUid");
|
super::check_unstable(state, "Deno.getUid");
|
||||||
state.borrow_mut::<Permissions>().env.check_all()?;
|
state.borrow_mut::<Permissions>().env.check_all()?;
|
||||||
unsafe { Ok(Some(libc::getuid())) }
|
// TODO(bartlomieju):
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
|
unsafe {
|
||||||
|
Ok(Some(libc::getuid()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
|
|
|
@ -174,6 +174,8 @@ fn op_run(state: &mut OpState, run_args: RunArgs) -> Result<RunInfo, AnyError> {
|
||||||
c.uid(uid);
|
c.uid(uid);
|
||||||
}
|
}
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
|
// TODO(bartlomieju):
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
unsafe {
|
unsafe {
|
||||||
c.pre_exec(|| {
|
c.pre_exec(|| {
|
||||||
libc::setgroups(0, std::ptr::null());
|
libc::setgroups(0, std::ptr::null());
|
||||||
|
|
|
@ -149,6 +149,8 @@ fn create_command(
|
||||||
command.uid(uid);
|
command.uid(uid);
|
||||||
}
|
}
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
|
// TODO(bartlomieju):
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
unsafe {
|
unsafe {
|
||||||
command.pre_exec(|| {
|
command.pre_exec(|| {
|
||||||
libc::setgroups(0, std::ptr::null());
|
libc::setgroups(0, std::ptr::null());
|
||||||
|
|
|
@ -172,12 +172,16 @@ fn op_isatty(state: &mut OpState, rid: ResourceId) -> Result<bool, AnyError> {
|
||||||
let handle = get_windows_handle(std_file)?;
|
let handle = get_windows_handle(std_file)?;
|
||||||
let mut test_mode: DWORD = 0;
|
let mut test_mode: DWORD = 0;
|
||||||
// If I cannot get mode out of console, it is not a console.
|
// If I cannot get mode out of console, it is not a console.
|
||||||
|
// TODO(bartlomieju):
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
Ok(unsafe { consoleapi::GetConsoleMode(handle, &mut test_mode) != FALSE })
|
Ok(unsafe { consoleapi::GetConsoleMode(handle, &mut test_mode) != FALSE })
|
||||||
}
|
}
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
{
|
{
|
||||||
use std::os::unix::io::AsRawFd;
|
use std::os::unix::io::AsRawFd;
|
||||||
let raw_fd = std_file.as_raw_fd();
|
let raw_fd = std_file.as_raw_fd();
|
||||||
|
// TODO(bartlomieju):
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
Ok(unsafe { libc::isatty(raw_fd as libc::c_int) == 1 })
|
Ok(unsafe { libc::isatty(raw_fd as libc::c_int) == 1 })
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
|
@ -225,6 +229,8 @@ fn op_console_size(
|
||||||
use std::os::unix::io::AsRawFd;
|
use std::os::unix::io::AsRawFd;
|
||||||
|
|
||||||
let fd = std_file.as_raw_fd();
|
let fd = std_file.as_raw_fd();
|
||||||
|
// TODO(bartlomieju):
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut size: libc::winsize = std::mem::zeroed();
|
let mut size: libc::winsize = std::mem::zeroed();
|
||||||
if libc::ioctl(fd, libc::TIOCGWINSZ, &mut size as *mut _) != 0 {
|
if libc::ioctl(fd, libc::TIOCGWINSZ, &mut size as *mut _) != 0 {
|
||||||
|
|
|
@ -1886,6 +1886,8 @@ fn permission_prompt(message: &str, name: &str) -> bool {
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
fn clear_stdin() -> Result<(), AnyError> {
|
fn clear_stdin() -> Result<(), AnyError> {
|
||||||
|
// TODO(bartlomieju):
|
||||||
|
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||||
let r = unsafe { libc::tcflush(0, libc::TCIFLUSH) };
|
let r = unsafe { libc::tcflush(0, libc::TCIFLUSH) };
|
||||||
assert_eq!(r, 0);
|
assert_eq!(r, 0);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -52,6 +52,8 @@ fn main() {
|
||||||
println!("x = {}", x);
|
println!("x = {}", x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SAFETY: all isolates have been destroyed, so we can now safely let V8 clean
|
||||||
|
// up its resources.
|
||||||
unsafe {
|
unsafe {
|
||||||
v8::V8::dispose();
|
v8::V8::dispose();
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,8 +87,10 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn bytes_layout() {
|
fn bytes_layout() {
|
||||||
|
// SAFETY: ensuring layout is the same
|
||||||
let u1: [usize; 4] =
|
let u1: [usize; 4] =
|
||||||
unsafe { mem::transmute(from_static(HELLO.as_bytes())) };
|
unsafe { mem::transmute(from_static(HELLO.as_bytes())) };
|
||||||
|
// SAFETY: ensuring layout is the same
|
||||||
let u2: [usize; 4] =
|
let u2: [usize; 4] =
|
||||||
unsafe { mem::transmute(bytes::Bytes::from_static(HELLO.as_bytes())) };
|
unsafe { mem::transmute(bytes::Bytes::from_static(HELLO.as_bytes())) };
|
||||||
assert_eq!(u1[..3], u2[..3]); // Struct bytes are equal besides Vtables
|
assert_eq!(u1[..3], u2[..3]); // Struct bytes are equal besides Vtables
|
||||||
|
|
|
@ -97,6 +97,8 @@ impl<T: serde::Serialize + 'static> From<T> for SerializablePkg {
|
||||||
fn from(x: T) -> Self {
|
fn from(x: T) -> Self {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn tc<T, U>(src: T) -> U {
|
fn tc<T, U>(src: T) -> U {
|
||||||
|
// SAFETY: the caller has ensured via the TypeId that the T and U types
|
||||||
|
// are the same.
|
||||||
let x = unsafe { transmute_copy(&src) };
|
let x = unsafe { transmute_copy(&src) };
|
||||||
std::mem::forget(src);
|
std::mem::forget(src);
|
||||||
x
|
x
|
||||||
|
|
|
@ -17,6 +17,7 @@ pub fn v8_init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn v8_shutdown() {
|
pub fn v8_shutdown() {
|
||||||
|
// SAFETY: this is safe, because all isolates have been shut down already.
|
||||||
unsafe {
|
unsafe {
|
||||||
v8::V8::dispose();
|
v8::V8::dispose();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
#![allow(clippy::undocumented_unsafe_blocks)]
|
||||||
|
|
||||||
use std::os::raw::c_void;
|
use std::os::raw::c_void;
|
||||||
use std::thread::sleep;
|
use std::thread::sleep;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
@ -11,23 +13,29 @@ pub extern "C" fn print_something() {
|
||||||
println!("something");
|
println!("something");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// The pointer to the buffer must be valid and initalized, and the length must
|
||||||
|
/// not be longer than the buffer's allocation.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn print_buffer(ptr: *const u8, len: usize) {
|
pub unsafe extern "C" fn print_buffer(ptr: *const u8, len: usize) {
|
||||||
let buf = unsafe { std::slice::from_raw_parts(ptr, len) };
|
let buf = std::slice::from_raw_parts(ptr, len);
|
||||||
println!("{:?}", buf);
|
println!("{:?}", buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// The pointer to the buffer must be valid and initalized, and the length must
|
||||||
|
/// not be longer than the buffer's allocation.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn print_buffer2(
|
pub unsafe extern "C" fn print_buffer2(
|
||||||
ptr1: *const u8,
|
ptr1: *const u8,
|
||||||
len1: usize,
|
len1: usize,
|
||||||
ptr2: *const u8,
|
ptr2: *const u8,
|
||||||
len2: usize,
|
len2: usize,
|
||||||
) {
|
) {
|
||||||
let buf1 = unsafe { std::slice::from_raw_parts(ptr1, len1) };
|
let buf1 = std::slice::from_raw_parts(ptr1, len1);
|
||||||
let buf2 = unsafe { std::slice::from_raw_parts(ptr2, len2) };
|
let buf2 = std::slice::from_raw_parts(ptr2, len2);
|
||||||
println!("{:?} {:?}", buf1, buf2);
|
println!("{:?} {:?}", buf1, buf2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,19 +95,25 @@ pub extern "C" fn sleep_blocking(ms: u64) {
|
||||||
sleep(duration);
|
sleep(duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// The pointer to the buffer must be valid and initalized, and the length must
|
||||||
|
/// not be longer than the buffer's allocation.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn fill_buffer(value: u8, buf: *mut u8, len: usize) {
|
pub unsafe extern "C" fn fill_buffer(value: u8, buf: *mut u8, len: usize) {
|
||||||
let buf = unsafe { std::slice::from_raw_parts_mut(buf, len) };
|
let buf = std::slice::from_raw_parts_mut(buf, len);
|
||||||
for itm in buf.iter_mut() {
|
for itm in buf.iter_mut() {
|
||||||
*itm = value;
|
*itm = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// The pointer to the buffer must be valid and initalized, and the length must
|
||||||
|
/// not be longer than the buffer's allocation.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn nonblocking_buffer(ptr: *const u8, len: usize) {
|
pub unsafe extern "C" fn nonblocking_buffer(ptr: *const u8, len: usize) {
|
||||||
let buf = unsafe { std::slice::from_raw_parts(ptr, len) };
|
let buf = std::slice::from_raw_parts(ptr, len);
|
||||||
assert_eq!(buf, vec![1, 2, 3, 4, 5, 6, 7, 8]);
|
assert_eq!(buf, vec![1, 2, 3, 4, 5, 6, 7, 8]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -116,6 +116,10 @@ async function clippy() {
|
||||||
"clippy::all",
|
"clippy::all",
|
||||||
"-D",
|
"-D",
|
||||||
"clippy::await_holding_refcell_ref",
|
"clippy::await_holding_refcell_ref",
|
||||||
|
"-D",
|
||||||
|
"clippy::missing_safety_doc",
|
||||||
|
"-D",
|
||||||
|
"clippy::undocumented_unsafe_blocks",
|
||||||
],
|
],
|
||||||
stdout: "inherit",
|
stdout: "inherit",
|
||||||
stderr: "inherit",
|
stderr: "inherit",
|
||||||
|
|
Loading…
Reference in a new issue