mirror of
https://github.com/denoland/deno.git
synced 2024-12-23 15:49:44 -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
d3e107768a
commit
86618e9bad
29 changed files with 294 additions and 87 deletions
|
@ -153,11 +153,13 @@ fn run(
|
|||
fn get_port() -> u16 {
|
||||
static mut NEXT_PORT: u16 = 4544;
|
||||
|
||||
let port = unsafe { NEXT_PORT };
|
||||
|
||||
unsafe {
|
||||
// TODO(bartlomieju):
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
let port = unsafe {
|
||||
let p = NEXT_PORT;
|
||||
NEXT_PORT += 1;
|
||||
}
|
||||
p
|
||||
};
|
||||
|
||||
port
|
||||
}
|
||||
|
|
|
@ -76,7 +76,13 @@ mod dirs {
|
|||
pub fn home_dir() -> Option<PathBuf> {
|
||||
std::env::var_os("HOME")
|
||||
.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)
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,11 @@ pub fn set_lsp_log_level(level: log::Level) {
|
|||
|
||||
pub fn lsp_log_level() -> log::Level {
|
||||
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
|
||||
|
|
|
@ -20,6 +20,8 @@ pub fn start(parent_process_id: u32) {
|
|||
|
||||
#[cfg(unix)]
|
||||
fn is_process_active(process_id: u32) -> bool {
|
||||
// TODO(bartlomieju):
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
unsafe {
|
||||
// signal of 0 checks for the existence of the process id
|
||||
libc::kill(process_id as i32, 0) == 0
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
/// This is the difference between `ulimit -n` and `ulimit -n -H`.
|
||||
pub fn raise_fd_limit() {
|
||||
#[cfg(unix)]
|
||||
// TODO(bartlomieju):
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
unsafe {
|
||||
let mut limits = libc::rlimit {
|
||||
rlim_cur: 0,
|
||||
|
|
|
@ -302,13 +302,19 @@ mod internal {
|
|||
Some((head, rc)) => {
|
||||
// Register this `Cancelable` node with a `CancelHandle` head node.
|
||||
assert_ne!(self, head);
|
||||
// TODO(piscisaureus): safety comment
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
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() };
|
||||
self_inner.link(waker, head_inner, rc)
|
||||
}
|
||||
None => {
|
||||
// This `Cancelable` has already been linked to a `CancelHandle` head
|
||||
// node; just update our stored `Waker` if necessary.
|
||||
// TODO(piscisaureus): safety comment
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
let inner = unsafe { &mut *self.inner.get() };
|
||||
inner.update_waker(waker)
|
||||
}
|
||||
|
@ -316,11 +322,15 @@ mod internal {
|
|||
}
|
||||
|
||||
pub fn cancel(&self) {
|
||||
// TODO(piscisaureus): safety comment
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
let inner = unsafe { &mut *self.inner.get() };
|
||||
inner.cancel();
|
||||
}
|
||||
|
||||
pub fn is_canceled(&self) -> bool {
|
||||
// TODO(piscisaureus): safety comment
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
let inner = unsafe { &mut *self.inner.get() };
|
||||
inner.is_canceled()
|
||||
}
|
||||
|
@ -337,6 +347,8 @@ mod internal {
|
|||
|
||||
impl Drop for Node {
|
||||
fn drop(&mut self) {
|
||||
// TODO(piscisaureus): safety comment
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
let inner = unsafe { &mut *self.inner.get() };
|
||||
inner.unlink();
|
||||
}
|
||||
|
@ -392,6 +404,8 @@ mod internal {
|
|||
prev: next_prev_nn,
|
||||
..
|
||||
} => {
|
||||
// TODO(piscisaureus): safety comment
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
let prev = unsafe { &mut *next_prev_nn.as_ptr() };
|
||||
match prev {
|
||||
NodeInner::Linked {
|
||||
|
@ -444,10 +458,14 @@ mod internal {
|
|||
if prev_nn == next_nn {
|
||||
// There were only two nodes in this chain; after unlinking ourselves
|
||||
// the other node is no longer linked.
|
||||
// TODO(piscisaureus): safety comment
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
let other = unsafe { prev_nn.as_mut() };
|
||||
*other = NodeInner::Unlinked;
|
||||
} else {
|
||||
// The chain had more than two nodes.
|
||||
// TODO(piscisaureus): safety comment
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
match unsafe { prev_nn.as_mut() } {
|
||||
NodeInner::Linked {
|
||||
next: prev_next_nn, ..
|
||||
|
@ -456,6 +474,8 @@ mod internal {
|
|||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
// TODO(piscisaureus): safety comment
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
match unsafe { next_nn.as_mut() } {
|
||||
NodeInner::Linked {
|
||||
prev: next_prev_nn, ..
|
||||
|
@ -473,6 +493,8 @@ mod internal {
|
|||
fn cancel(&mut self) {
|
||||
let mut head_nn = NonNull::from(self);
|
||||
|
||||
// TODO(piscisaureus): safety comment
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
// Mark the head node as canceled.
|
||||
let mut item_nn =
|
||||
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`.
|
||||
while item_nn != head_nn {
|
||||
// TODO(piscisaureus): safety comment
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
match replace(unsafe { item_nn.as_mut() }, NodeInner::Canceled) {
|
||||
NodeInner::Linked {
|
||||
kind: NodeKind::Item { waker },
|
||||
|
@ -745,6 +769,7 @@ mod tests {
|
|||
assert!(Rc::get_mut(&mut cancel_handle).is_some());
|
||||
|
||||
let mut future = pending::<Never>().or_cancel(&cancel_handle);
|
||||
// SAFETY: `Cancelable` pins the future
|
||||
let future = unsafe { Pin::new_unchecked(&mut future) };
|
||||
|
||||
// There are two `Rc<CancelHandle>` references now, so this fails.
|
||||
|
|
|
@ -157,12 +157,16 @@ impl<T: 'static> RcRef<T> {
|
|||
map_fn: F,
|
||||
) -> RcRef<T> {
|
||||
let RcRef::<S> { rc, value } = source.into();
|
||||
// TODO(piscisaureus): safety comment
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
let value = map_fn(unsafe { &*value });
|
||||
RcRef { rc, value }
|
||||
}
|
||||
|
||||
pub(crate) fn split(rc_ref: &Self) -> (&T, &Rc<dyn Any>) {
|
||||
let &Self { ref rc, value } = rc_ref;
|
||||
// TODO(piscisaureus): safety comment
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
(unsafe { &*value }, rc)
|
||||
}
|
||||
}
|
||||
|
@ -206,7 +210,11 @@ impl<T: 'static> From<&Rc<T>> for RcRef<T> {
|
|||
impl<T> Deref for RcRef<T> {
|
||||
type Target = T;
|
||||
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
|
||||
// enqueued waiters, return `None`, even if the current borrow is a shared
|
||||
// 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() };
|
||||
if waiters.is_empty() {
|
||||
// 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 turn = self.turn.get();
|
||||
let index = {
|
||||
// TODO(piscisaureus): safety comment
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
let waiters = unsafe { &mut *self.waiters.as_ptr() };
|
||||
waiters.push_back(Some(waiter));
|
||||
waiters.len() - 1
|
||||
|
@ -315,6 +327,8 @@ mod internal {
|
|||
Poll::Ready(())
|
||||
} else {
|
||||
// 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() };
|
||||
// Sanity check: id cannot be higher than the last queue element.
|
||||
assert!(id < turn + waiters.len());
|
||||
|
@ -330,6 +344,8 @@ mod internal {
|
|||
|
||||
fn wake_waiters(&self) {
|
||||
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 mut turn = self.turn.get();
|
||||
|
||||
|
@ -379,6 +395,8 @@ mod internal {
|
|||
self.drop_borrow::<M>();
|
||||
} else {
|
||||
// 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() };
|
||||
waiters[id - turn].take().unwrap();
|
||||
}
|
||||
|
@ -411,6 +429,8 @@ mod internal {
|
|||
type Output = AsyncBorrowImpl<T, M>;
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||
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 cell = self_mut.cell.take().unwrap();
|
||||
Poll::Ready(AsyncBorrowImpl::<T, M>::new(cell))
|
||||
|
@ -448,7 +468,11 @@ mod internal {
|
|||
impl<T, M: BorrowModeTrait> Deref for AsyncBorrowImpl<T, M> {
|
||||
type Target = T;
|
||||
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> {
|
||||
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>,
|
||||
import_assertions: v8::Local<v8::FixedArray>,
|
||||
) -> *mut v8::Promise {
|
||||
// SAFETY: `CallbackScope` can be safely constructed from `Local<Context>`
|
||||
let scope = &mut unsafe { v8::CallbackScope::new(context) };
|
||||
|
||||
// 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>,
|
||||
meta: v8::Local<v8::Object>,
|
||||
) {
|
||||
// SAFETY: `CallbackScope` can be safely constructed from `Local<Context>`
|
||||
let scope = &mut unsafe { v8::CallbackScope::new(context) };
|
||||
let module_map_rc = JsRuntime::module_map(scope);
|
||||
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) {
|
||||
use v8::PromiseRejectEvent::*;
|
||||
|
||||
// SAFETY: `CallbackScope` can be safely constructed from `&PromiseRejectMessage`
|
||||
let scope = &mut unsafe { v8::CallbackScope::new(&message) };
|
||||
|
||||
let state_rc = JsRuntime::state(scope);
|
||||
|
@ -418,6 +421,7 @@ pub fn module_resolve_callback<'s>(
|
|||
import_assertions: v8::Local<'s, v8::FixedArray>,
|
||||
referrer: 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 module_map_rc = JsRuntime::module_map(scope);
|
||||
|
|
|
@ -485,6 +485,8 @@ impl task::ArcWake for InspectorWaker {
|
|||
_isolate: &mut v8::Isolate,
|
||||
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.poll_sessions(None);
|
||||
}
|
||||
|
@ -521,6 +523,8 @@ impl InspectorSession {
|
|||
let v8_channel = v8::inspector::ChannelBase::new::<Self>();
|
||||
let mut v8_inspector = v8_inspector_rc.borrow_mut();
|
||||
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(
|
||||
Self::CONTEXT_GROUP_ID,
|
||||
// Todo(piscisaureus): V8Inspector::connect() should require that
|
||||
|
@ -544,6 +548,8 @@ impl InspectorSession {
|
|||
msg: String,
|
||||
) {
|
||||
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 {
|
||||
(*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> {
|
||||
let b = Box::new(MaybeUninit::<T>::uninit());
|
||||
let p = Box::into_raw(b) as *mut T;
|
||||
unsafe { ptr::write(p, new_fn(p)) };
|
||||
unsafe { Box::from_raw(p) }
|
||||
// SAFETY: memory layout for `T` is ensured on first line of this function
|
||||
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>,
|
||||
module: v8::Local<v8::Module>,
|
||||
) -> Option<v8::Local<'a, v8::Value>> {
|
||||
// SAFETY: `CallbackScope` can be safely constructed from `Local<Context>`
|
||||
let scope = &mut unsafe { v8::CallbackScope::new(context) };
|
||||
let tc_scope = &mut v8::TryCatch::new(scope);
|
||||
let module_map = tc_scope
|
||||
|
|
|
@ -63,6 +63,8 @@ impl<T> Future for OpCall<T> {
|
|||
self: std::pin::Pin<&mut Self>,
|
||||
cx: &mut std::task::Context<'_>,
|
||||
) -> std::task::Poll<Self::Output> {
|
||||
// TODO(piscisaureus): safety comment
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
let inner = unsafe { &mut self.get_unchecked_mut().0 };
|
||||
let mut pinned = Pin::new(inner);
|
||||
ready!(pinned.as_mut().poll(cx));
|
||||
|
|
|
@ -56,12 +56,17 @@ impl OpsTracker {
|
|||
#[allow(clippy::mut_from_ref)]
|
||||
#[inline]
|
||||
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() }
|
||||
}
|
||||
|
||||
#[allow(clippy::mut_from_ref)]
|
||||
#[inline]
|
||||
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) }
|
||||
}
|
||||
|
||||
|
|
|
@ -77,6 +77,8 @@ impl dyn Resource {
|
|||
pub fn downcast_rc<'a, T: Resource>(self: &'a Rc<Self>) -> Option<&'a Rc<T>> {
|
||||
if self.is::<T>() {
|
||||
let ptr = self as *const Rc<_> as *const Rc<T>;
|
||||
// TODO(piscisaureus): safety comment
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
Some(unsafe { &*ptr })
|
||||
} else {
|
||||
None
|
||||
|
|
|
@ -333,6 +333,9 @@ impl JsRuntime {
|
|||
assert!(options.startup_snapshot.is_none());
|
||||
let mut creator =
|
||||
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 mut isolate = JsRuntime::setup_isolate(isolate);
|
||||
{
|
||||
|
@ -1028,6 +1031,8 @@ extern "C" fn near_heap_limit_callback<F>(
|
|||
where
|
||||
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) };
|
||||
callback(current_heap_limit, initial_heap_limit)
|
||||
}
|
||||
|
|
128
ext/ffi/lib.rs
128
ext/ffi/lib.rs
|
@ -130,6 +130,8 @@ impl DynamicLibraryResource {
|
|||
// By default, Err returned by this function does not tell
|
||||
// which symbol wasn't exported. So we'll modify the error
|
||||
// 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) } {
|
||||
Ok(value) => Ok(value),
|
||||
Err(err) => Err(generic_error(format!(
|
||||
|
@ -164,6 +166,8 @@ impl DynamicLibraryResource {
|
|||
// By default, Err returned by this function does not tell
|
||||
// which symbol wasn't exported. So we'll modify the error
|
||||
// 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) } {
|
||||
Ok(value) => Ok(Ok(value)),
|
||||
Err(err) => Err(generic_error(format!(
|
||||
|
@ -743,55 +747,60 @@ fn ffi_call(
|
|||
let call_args: Vec<Arg> = call_args
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(index, ffi_arg)| unsafe {
|
||||
ffi_arg.as_arg(*parameter_types.get(index).unwrap())
|
||||
.map(|(index, ffi_arg)| {
|
||||
// SAFETY: the union field is initialized
|
||||
unsafe { ffi_arg.as_arg(*parameter_types.get(index).unwrap()) }
|
||||
})
|
||||
.collect();
|
||||
|
||||
Ok(match result_type {
|
||||
NativeType::Void => NativeValue {
|
||||
void_value: unsafe { cif.call::<()>(fun_ptr, &call_args) },
|
||||
},
|
||||
NativeType::U8 => NativeValue {
|
||||
u8_value: unsafe { cif.call::<u8>(fun_ptr, &call_args) },
|
||||
},
|
||||
NativeType::I8 => NativeValue {
|
||||
i8_value: unsafe { cif.call::<i8>(fun_ptr, &call_args) },
|
||||
},
|
||||
NativeType::U16 => NativeValue {
|
||||
u16_value: unsafe { cif.call::<u16>(fun_ptr, &call_args) },
|
||||
},
|
||||
NativeType::I16 => NativeValue {
|
||||
i16_value: unsafe { cif.call::<i16>(fun_ptr, &call_args) },
|
||||
},
|
||||
NativeType::U32 => NativeValue {
|
||||
u32_value: unsafe { cif.call::<u32>(fun_ptr, &call_args) },
|
||||
},
|
||||
NativeType::I32 => NativeValue {
|
||||
i32_value: unsafe { cif.call::<i32>(fun_ptr, &call_args) },
|
||||
},
|
||||
NativeType::U64 => NativeValue {
|
||||
u64_value: unsafe { cif.call::<u64>(fun_ptr, &call_args) },
|
||||
},
|
||||
NativeType::I64 => NativeValue {
|
||||
i64_value: unsafe { cif.call::<i64>(fun_ptr, &call_args) },
|
||||
},
|
||||
NativeType::USize => NativeValue {
|
||||
usize_value: unsafe { cif.call::<usize>(fun_ptr, &call_args) },
|
||||
},
|
||||
NativeType::ISize => NativeValue {
|
||||
isize_value: unsafe { cif.call::<isize>(fun_ptr, &call_args) },
|
||||
},
|
||||
NativeType::F32 => NativeValue {
|
||||
f32_value: unsafe { cif.call::<f32>(fun_ptr, &call_args) },
|
||||
},
|
||||
NativeType::F64 => NativeValue {
|
||||
f64_value: unsafe { cif.call::<f64>(fun_ptr, &call_args) },
|
||||
},
|
||||
NativeType::Pointer | NativeType::Function => NativeValue {
|
||||
pointer: unsafe { cif.call::<*const u8>(fun_ptr, &call_args) },
|
||||
},
|
||||
})
|
||||
// SAFETY: types in the `Cif` match the actual calling convention and
|
||||
// types of symbol.
|
||||
unsafe {
|
||||
Ok(match result_type {
|
||||
NativeType::Void => NativeValue {
|
||||
void_value: cif.call::<()>(fun_ptr, &call_args),
|
||||
},
|
||||
NativeType::U8 => NativeValue {
|
||||
u8_value: cif.call::<u8>(fun_ptr, &call_args),
|
||||
},
|
||||
NativeType::I8 => NativeValue {
|
||||
i8_value: cif.call::<i8>(fun_ptr, &call_args),
|
||||
},
|
||||
NativeType::U16 => NativeValue {
|
||||
u16_value: cif.call::<u16>(fun_ptr, &call_args),
|
||||
},
|
||||
NativeType::I16 => NativeValue {
|
||||
i16_value: cif.call::<i16>(fun_ptr, &call_args),
|
||||
},
|
||||
NativeType::U32 => NativeValue {
|
||||
u32_value: cif.call::<u32>(fun_ptr, &call_args),
|
||||
},
|
||||
NativeType::I32 => NativeValue {
|
||||
i32_value: cif.call::<i32>(fun_ptr, &call_args),
|
||||
},
|
||||
NativeType::U64 => NativeValue {
|
||||
u64_value: cif.call::<u64>(fun_ptr, &call_args),
|
||||
},
|
||||
NativeType::I64 => NativeValue {
|
||||
i64_value: cif.call::<i64>(fun_ptr, &call_args),
|
||||
},
|
||||
NativeType::USize => NativeValue {
|
||||
usize_value: cif.call::<usize>(fun_ptr, &call_args),
|
||||
},
|
||||
NativeType::ISize => NativeValue {
|
||||
isize_value: cif.call::<isize>(fun_ptr, &call_args),
|
||||
},
|
||||
NativeType::F32 => NativeValue {
|
||||
f32_value: cif.call::<f32>(fun_ptr, &call_args),
|
||||
},
|
||||
NativeType::F64 => NativeValue {
|
||||
f64_value: cif.call::<f64>(fun_ptr, &call_args),
|
||||
},
|
||||
NativeType::Pointer | NativeType::Function => NativeValue {
|
||||
pointer: cif.call::<*const u8>(fun_ptr, &call_args),
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
struct UnsafeCallbackResource {
|
||||
|
@ -1201,71 +1210,83 @@ fn op_ffi_get_static<'scope>(
|
|||
return Err(type_error("Invalid FFI static type 'void'"));
|
||||
}
|
||||
NativeType::U8 => {
|
||||
// SAFETY: ptr is user provided
|
||||
let result = unsafe { ptr::read_unaligned(data_ptr as *const u8) };
|
||||
let number: v8::Local<v8::Value> =
|
||||
v8::Integer::new_from_unsigned(scope, result as u32).into();
|
||||
number.into()
|
||||
}
|
||||
NativeType::I8 => {
|
||||
// SAFETY: ptr is user provided
|
||||
let result = unsafe { ptr::read_unaligned(data_ptr as *const i8) };
|
||||
let number: v8::Local<v8::Value> =
|
||||
v8::Integer::new(scope, result as i32).into();
|
||||
number.into()
|
||||
}
|
||||
NativeType::U16 => {
|
||||
// SAFETY: ptr is user provided
|
||||
let result = unsafe { ptr::read_unaligned(data_ptr as *const u16) };
|
||||
let number: v8::Local<v8::Value> =
|
||||
v8::Integer::new_from_unsigned(scope, result as u32).into();
|
||||
number.into()
|
||||
}
|
||||
NativeType::I16 => {
|
||||
// SAFETY: ptr is user provided
|
||||
let result = unsafe { ptr::read_unaligned(data_ptr as *const i16) };
|
||||
let number: v8::Local<v8::Value> =
|
||||
v8::Integer::new(scope, result as i32).into();
|
||||
number.into()
|
||||
}
|
||||
NativeType::U32 => {
|
||||
// SAFETY: ptr is user provided
|
||||
let result = unsafe { ptr::read_unaligned(data_ptr as *const u32) };
|
||||
let number: v8::Local<v8::Value> =
|
||||
v8::Integer::new_from_unsigned(scope, result).into();
|
||||
number.into()
|
||||
}
|
||||
NativeType::I32 => {
|
||||
// SAFETY: ptr is user provided
|
||||
let result = unsafe { ptr::read_unaligned(data_ptr as *const i32) };
|
||||
let number: v8::Local<v8::Value> = v8::Integer::new(scope, result).into();
|
||||
number.into()
|
||||
}
|
||||
NativeType::U64 => {
|
||||
// SAFETY: ptr is user provided
|
||||
let result = unsafe { ptr::read_unaligned(data_ptr as *const u64) };
|
||||
let big_int: v8::Local<v8::Value> =
|
||||
v8::BigInt::new_from_u64(scope, result).into();
|
||||
big_int.into()
|
||||
}
|
||||
NativeType::I64 => {
|
||||
// SAFETY: ptr is user provided
|
||||
let result = unsafe { ptr::read_unaligned(data_ptr as *const i64) };
|
||||
let big_int: v8::Local<v8::Value> =
|
||||
v8::BigInt::new_from_i64(scope, result).into();
|
||||
big_int.into()
|
||||
}
|
||||
NativeType::USize => {
|
||||
// SAFETY: ptr is user provided
|
||||
let result = unsafe { ptr::read_unaligned(data_ptr as *const usize) };
|
||||
let big_int: v8::Local<v8::Value> =
|
||||
v8::BigInt::new_from_u64(scope, result as u64).into();
|
||||
big_int.into()
|
||||
}
|
||||
NativeType::ISize => {
|
||||
// SAFETY: ptr is user provided
|
||||
let result = unsafe { ptr::read_unaligned(data_ptr as *const isize) };
|
||||
let big_int: v8::Local<v8::Value> =
|
||||
v8::BigInt::new_from_i64(scope, result as i64).into();
|
||||
big_int.into()
|
||||
}
|
||||
NativeType::F32 => {
|
||||
// SAFETY: ptr is user provided
|
||||
let result = unsafe { ptr::read_unaligned(data_ptr as *const f32) };
|
||||
let number: v8::Local<v8::Value> =
|
||||
v8::Number::new(scope, result as f64).into();
|
||||
number.into()
|
||||
}
|
||||
NativeType::F64 => {
|
||||
// SAFETY: ptr is user provided
|
||||
let result = unsafe { ptr::read_unaligned(data_ptr as *const f64) };
|
||||
let number: v8::Local<v8::Value> = v8::Number::new(scope, result).into();
|
||||
number.into()
|
||||
|
@ -1339,7 +1360,7 @@ fn op_ffi_call_nonblocking<'scope>(
|
|||
cif,
|
||||
ptr,
|
||||
parameter_types,
|
||||
..
|
||||
result_type,
|
||||
} = symbol.clone();
|
||||
ffi_call(call_args, &cif, ptr, ¶meter_types, result_type)
|
||||
});
|
||||
|
@ -1392,6 +1413,8 @@ where
|
|||
))
|
||||
} else {
|
||||
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) };
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1411,6 +1434,8 @@ where
|
|||
permissions.check(None)?;
|
||||
|
||||
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())
|
||||
}
|
||||
|
||||
|
@ -1427,6 +1452,7 @@ where
|
|||
let permissions = state.borrow_mut::<FP>();
|
||||
permissions.check(None)?;
|
||||
|
||||
// SAFETY: ptr is user provided.
|
||||
Ok(unsafe { ptr::read_unaligned(ptr as *const u8) })
|
||||
}
|
||||
|
||||
|
@ -1443,6 +1469,7 @@ where
|
|||
let permissions = state.borrow_mut::<FP>();
|
||||
permissions.check(None)?;
|
||||
|
||||
// SAFETY: ptr is user provided.
|
||||
Ok(unsafe { ptr::read_unaligned(ptr as *const i8) })
|
||||
}
|
||||
|
||||
|
@ -1459,6 +1486,7 @@ where
|
|||
let permissions = state.borrow_mut::<FP>();
|
||||
permissions.check(None)?;
|
||||
|
||||
// SAFETY: ptr is user provided.
|
||||
Ok(unsafe { ptr::read_unaligned(ptr as *const u16) })
|
||||
}
|
||||
|
||||
|
@ -1475,6 +1503,7 @@ where
|
|||
let permissions = state.borrow_mut::<FP>();
|
||||
permissions.check(None)?;
|
||||
|
||||
// SAFETY: ptr is user provided.
|
||||
Ok(unsafe { ptr::read_unaligned(ptr as *const i16) })
|
||||
}
|
||||
|
||||
|
@ -1491,6 +1520,7 @@ where
|
|||
let permissions = state.borrow_mut::<FP>();
|
||||
permissions.check(None)?;
|
||||
|
||||
// SAFETY: ptr is user provided.
|
||||
Ok(unsafe { ptr::read_unaligned(ptr as *const u32) })
|
||||
}
|
||||
|
||||
|
@ -1507,6 +1537,7 @@ where
|
|||
let permissions = state.borrow_mut::<FP>();
|
||||
permissions.check(None)?;
|
||||
|
||||
// SAFETY: ptr is user provided.
|
||||
Ok(unsafe { ptr::read_unaligned(ptr as *const i32) })
|
||||
}
|
||||
|
||||
|
@ -1525,6 +1556,7 @@ where
|
|||
let permissions = state.borrow_mut::<FP>();
|
||||
permissions.check(None)?;
|
||||
|
||||
// SAFETY: ptr is user provided.
|
||||
let result = unsafe { ptr::read_unaligned(ptr as *const u64) };
|
||||
|
||||
let big_int: v8::Local<v8::Value> =
|
||||
|
@ -1545,6 +1577,7 @@ where
|
|||
let permissions = state.borrow_mut::<FP>();
|
||||
permissions.check(None)?;
|
||||
|
||||
// SAFETY: ptr is user provided.
|
||||
Ok(unsafe { ptr::read_unaligned(ptr as *const f32) })
|
||||
}
|
||||
|
||||
|
@ -1561,6 +1594,7 @@ where
|
|||
let permissions = state.borrow_mut::<FP>();
|
||||
permissions.check(None)?;
|
||||
|
||||
// SAFETY: ptr is user provided.
|
||||
Ok(unsafe { ptr::read_unaligned(ptr as *const f64) })
|
||||
}
|
||||
|
||||
|
|
|
@ -375,11 +375,17 @@ impl TlsStreamInner {
|
|||
ready!(self.poll_io(cx, Flow::Read))?;
|
||||
|
||||
if self.rd_state == State::StreamOpen {
|
||||
// TODO(bartlomieju):
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
let buf_slice =
|
||||
unsafe { &mut *(buf.unfilled_mut() as *mut [_] as *mut [u8]) };
|
||||
let bytes_read = self.tls.reader().read(buf_slice)?;
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -581,10 +587,16 @@ impl Shared {
|
|||
let self_weak = Arc::downgrade(self);
|
||||
let self_ptr = self_weak.into_raw() as *const ();
|
||||
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 {
|
||||
// TODO(bartlomieju):
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
let self_weak = unsafe { Weak::from_raw(self_ptr as *const Self) };
|
||||
let ptr1 = self_weak.clone().into_raw();
|
||||
let ptr2 = self_weak.into_raw();
|
||||
|
@ -598,6 +610,8 @@ impl Shared {
|
|||
}
|
||||
|
||||
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) };
|
||||
if let Some(self_arc) = Weak::upgrade(&self_weak) {
|
||||
self_arc.rd_waker.wake();
|
||||
|
@ -607,6 +621,8 @@ impl Shared {
|
|||
}
|
||||
|
||||
fn drop_shared_waker(self_ptr: *const ()) {
|
||||
// TODO(bartlomieju):
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
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,
|
||||
) {
|
||||
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) };
|
||||
boxed_sender
|
||||
.send(match status {
|
||||
|
@ -188,6 +190,8 @@ pub fn op_webgpu_buffer_get_mapped_range(
|
|||
))
|
||||
.map_err(|e| DomExceptionOperationError::new(&e.to_string()))?;
|
||||
|
||||
// TODO(bartlomieju):
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
let slice = unsafe {
|
||||
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;
|
||||
|
||||
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) };
|
||||
slice.copy_from_slice(&buffer);
|
||||
}
|
||||
|
|
|
@ -42,26 +42,35 @@ use {
|
|||
// alive for the duration of the application since the last handle/fd
|
||||
// being dropped will close the corresponding pipe.
|
||||
#[cfg(unix)]
|
||||
static STDIN_HANDLE: Lazy<StdFile> =
|
||||
Lazy::new(|| unsafe { StdFile::from_raw_fd(0) });
|
||||
static STDIN_HANDLE: Lazy<StdFile> = Lazy::new(|| {
|
||||
// SAFETY: corresponds to OS stdin
|
||||
unsafe { StdFile::from_raw_fd(0) }
|
||||
});
|
||||
#[cfg(unix)]
|
||||
static STDOUT_HANDLE: Lazy<StdFile> =
|
||||
Lazy::new(|| unsafe { StdFile::from_raw_fd(1) });
|
||||
static STDOUT_HANDLE: Lazy<StdFile> = Lazy::new(|| {
|
||||
// SAFETY: corresponds to OS stdout
|
||||
unsafe { StdFile::from_raw_fd(1) }
|
||||
});
|
||||
#[cfg(unix)]
|
||||
static STDERR_HANDLE: Lazy<StdFile> =
|
||||
Lazy::new(|| unsafe { StdFile::from_raw_fd(2) });
|
||||
static STDERR_HANDLE: Lazy<StdFile> = Lazy::new(|| {
|
||||
// SAFETY: corresponds to OS stderr
|
||||
unsafe { StdFile::from_raw_fd(2) }
|
||||
});
|
||||
|
||||
#[cfg(windows)]
|
||||
static STDIN_HANDLE: Lazy<StdFile> = Lazy::new(|| unsafe {
|
||||
StdFile::from_raw_handle(GetStdHandle(winbase::STD_INPUT_HANDLE))
|
||||
static STDIN_HANDLE: Lazy<StdFile> = Lazy::new(|| {
|
||||
// SAFETY: corresponds to OS stdin
|
||||
unsafe { StdFile::from_raw_handle(GetStdHandle(winbase::STD_INPUT_HANDLE)) }
|
||||
});
|
||||
#[cfg(windows)]
|
||||
static STDOUT_HANDLE: Lazy<StdFile> = Lazy::new(|| unsafe {
|
||||
StdFile::from_raw_handle(GetStdHandle(winbase::STD_OUTPUT_HANDLE))
|
||||
static STDOUT_HANDLE: Lazy<StdFile> = Lazy::new(|| {
|
||||
// SAFETY: corresponds to OS stdout
|
||||
unsafe { StdFile::from_raw_handle(GetStdHandle(winbase::STD_OUTPUT_HANDLE)) }
|
||||
});
|
||||
#[cfg(windows)]
|
||||
static STDERR_HANDLE: Lazy<StdFile> = Lazy::new(|| unsafe {
|
||||
StdFile::from_raw_handle(GetStdHandle(winbase::STD_ERROR_HANDLE))
|
||||
static STDERR_HANDLE: Lazy<StdFile> = Lazy::new(|| {
|
||||
// SAFETY: corresponds to OS stderr
|
||||
unsafe { StdFile::from_raw_handle(GetStdHandle(winbase::STD_ERROR_HANDLE)) }
|
||||
});
|
||||
|
||||
pub fn init() -> Extension {
|
||||
|
|
|
@ -248,7 +248,11 @@ fn op_system_memory_info(
|
|||
fn op_getgid(state: &mut OpState) -> Result<Option<u32>, AnyError> {
|
||||
super::check_unstable(state, "Deno.getGid");
|
||||
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)]
|
||||
|
@ -264,7 +268,11 @@ fn op_getgid(state: &mut OpState) -> Result<Option<u32>, AnyError> {
|
|||
fn op_getuid(state: &mut OpState) -> Result<Option<u32>, AnyError> {
|
||||
super::check_unstable(state, "Deno.getUid");
|
||||
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)]
|
||||
|
|
|
@ -174,6 +174,8 @@ fn op_run(state: &mut OpState, run_args: RunArgs) -> Result<RunInfo, AnyError> {
|
|||
c.uid(uid);
|
||||
}
|
||||
#[cfg(unix)]
|
||||
// TODO(bartlomieju):
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
unsafe {
|
||||
c.pre_exec(|| {
|
||||
libc::setgroups(0, std::ptr::null());
|
||||
|
|
|
@ -149,6 +149,8 @@ fn create_command(
|
|||
command.uid(uid);
|
||||
}
|
||||
#[cfg(unix)]
|
||||
// TODO(bartlomieju):
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
unsafe {
|
||||
command.pre_exec(|| {
|
||||
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 mut test_mode: DWORD = 0;
|
||||
// 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 })
|
||||
}
|
||||
#[cfg(unix)]
|
||||
{
|
||||
use std::os::unix::io::AsRawFd;
|
||||
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 })
|
||||
}
|
||||
})?;
|
||||
|
@ -225,6 +229,8 @@ fn op_console_size(
|
|||
use std::os::unix::io::AsRawFd;
|
||||
|
||||
let fd = std_file.as_raw_fd();
|
||||
// TODO(bartlomieju):
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
unsafe {
|
||||
let mut size: libc::winsize = std::mem::zeroed();
|
||||
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)]
|
||||
fn clear_stdin() -> Result<(), AnyError> {
|
||||
// TODO(bartlomieju):
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
let r = unsafe { libc::tcflush(0, libc::TCIFLUSH) };
|
||||
assert_eq!(r, 0);
|
||||
Ok(())
|
||||
|
|
|
@ -52,6 +52,8 @@ fn main() {
|
|||
println!("x = {}", x);
|
||||
}
|
||||
|
||||
// SAFETY: all isolates have been destroyed, so we can now safely let V8 clean
|
||||
// up its resources.
|
||||
unsafe {
|
||||
v8::V8::dispose();
|
||||
}
|
||||
|
|
|
@ -87,8 +87,10 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn bytes_layout() {
|
||||
// SAFETY: ensuring layout is the same
|
||||
let u1: [usize; 4] =
|
||||
unsafe { mem::transmute(from_static(HELLO.as_bytes())) };
|
||||
// SAFETY: ensuring layout is the same
|
||||
let u2: [usize; 4] =
|
||||
unsafe { mem::transmute(bytes::Bytes::from_static(HELLO.as_bytes())) };
|
||||
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 {
|
||||
#[inline(always)]
|
||||
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) };
|
||||
std::mem::forget(src);
|
||||
x
|
||||
|
|
|
@ -17,6 +17,7 @@ pub fn v8_init() {
|
|||
}
|
||||
|
||||
pub fn v8_shutdown() {
|
||||
// SAFETY: this is safe, because all isolates have been shut down already.
|
||||
unsafe {
|
||||
v8::V8::dispose();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
#![allow(clippy::undocumented_unsafe_blocks)]
|
||||
|
||||
use std::os::raw::c_void;
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
|
@ -11,23 +13,29 @@ pub extern "C" fn print_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]
|
||||
pub extern "C" fn print_buffer(ptr: *const u8, len: usize) {
|
||||
let buf = unsafe { std::slice::from_raw_parts(ptr, len) };
|
||||
pub unsafe extern "C" fn print_buffer(ptr: *const u8, len: usize) {
|
||||
let buf = std::slice::from_raw_parts(ptr, len);
|
||||
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]
|
||||
pub extern "C" fn print_buffer2(
|
||||
pub unsafe extern "C" fn print_buffer2(
|
||||
ptr1: *const u8,
|
||||
len1: usize,
|
||||
ptr2: *const u8,
|
||||
len2: usize,
|
||||
) {
|
||||
let buf1 = unsafe { std::slice::from_raw_parts(ptr1, len1) };
|
||||
let buf2 = unsafe { std::slice::from_raw_parts(ptr2, len2) };
|
||||
let buf1 = std::slice::from_raw_parts(ptr1, len1);
|
||||
let buf2 = std::slice::from_raw_parts(ptr2, len2);
|
||||
println!("{:?} {:?}", buf1, buf2);
|
||||
}
|
||||
|
||||
|
@ -87,19 +95,25 @@ pub extern "C" fn sleep_blocking(ms: u64) {
|
|||
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]
|
||||
pub extern "C" fn fill_buffer(value: u8, buf: *mut u8, len: usize) {
|
||||
let buf = unsafe { std::slice::from_raw_parts_mut(buf, len) };
|
||||
pub unsafe extern "C" fn fill_buffer(value: u8, buf: *mut u8, len: usize) {
|
||||
let buf = std::slice::from_raw_parts_mut(buf, len);
|
||||
for itm in buf.iter_mut() {
|
||||
*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]
|
||||
pub extern "C" fn nonblocking_buffer(ptr: *const u8, len: usize) {
|
||||
let buf = unsafe { std::slice::from_raw_parts(ptr, len) };
|
||||
pub unsafe extern "C" fn nonblocking_buffer(ptr: *const u8, len: usize) {
|
||||
let buf = std::slice::from_raw_parts(ptr, len);
|
||||
assert_eq!(buf, vec![1, 2, 3, 4, 5, 6, 7, 8]);
|
||||
}
|
||||
|
||||
|
|
|
@ -116,6 +116,10 @@ async function clippy() {
|
|||
"clippy::all",
|
||||
"-D",
|
||||
"clippy::await_holding_refcell_ref",
|
||||
"-D",
|
||||
"clippy::missing_safety_doc",
|
||||
"-D",
|
||||
"clippy::undocumented_unsafe_blocks",
|
||||
],
|
||||
stdout: "inherit",
|
||||
stderr: "inherit",
|
||||
|
|
Loading…
Reference in a new issue