Skip to content
Closed

ai slop #38315

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 0 additions & 13 deletions src/jsc/JSValue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1812,19 +1812,6 @@ impl FromAny for &str {
bun_string_jsc::create_utf8_for_js(global, self.as_bytes())
}
}
impl FromAny for Box<[bun_core::String]> {
/// The boxed
/// slice is consumed: every element's WTF refcount is dropped and the
/// backing allocation freed via `Box` drop. `bun_core::String` is `Copy`
/// with no `Drop`, so the explicit `deref()` loop is required.
fn into_js_value(self, global: &JSGlobalObject) -> JsResult<JSValue> {
let result = bun_string_jsc::to_js_array(global, &self);
for out in self.iter() {
out.deref();
}
result
}
}
impl<T: FromAny> FromAny for Option<T> {
/// `None` → `undefined`.
#[inline]
Expand Down
12 changes: 4 additions & 8 deletions src/runtime/api/JSTranspiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -654,7 +654,7 @@ impl Config {
/// which the job's Js side keeps alive and the pool borrow keeps valid.
pub(crate) struct TransformTask {
pub input_code: bun_jsc::ThreadSafe<StringOrBuffer>,
pub output_code: BunString,
pub output_code: OwnedString,
pub transpiler: core::mem::ManuallyDrop<Transpiler::Transpiler<'static>>,
pub log: bun_ast::Log,
pub err: Option<Error>,
Expand Down Expand Up @@ -719,7 +719,7 @@ impl TransformTask {

let task = TransformTask {
input_code,
output_code: BunString::empty(),
output_code: OwnedString::default(),
transpiler: transpiler_copy,
macro_map: clone_macro_map(&config.macro_map),
tsconfig: config
Expand Down Expand Up @@ -831,7 +831,6 @@ impl TransformTask {
};

if parse_result.empty {
self.output_code = BunString::empty();
return;
}

Expand Down Expand Up @@ -861,9 +860,7 @@ impl TransformTask {
buffer_writer = printer.ctx;
// `written()` reslices via `written_len`; copy out the printed
// bytes, then the local writer is dropped.
self.output_code = BunString::clone_utf8(buffer_writer.written());
} else {
self.output_code = BunString::empty();
self.output_code = OwnedString::new(BunString::clone_utf8(buffer_writer.written()));
}
}

Expand All @@ -872,8 +869,7 @@ impl TransformTask {
promise: &mut JSPromise,
global: &JSGlobalObject,
) -> Result<(), bun_jsc::JsTerminated> {
// The job drops this `TransformTask` (running its `Drop`: transpiler
// deref etc.) right after `then` returns.
// The job drops this `TransformTask` right after `then` returns.
if self.log.has_any() || self.err.is_some() {
let error_value: JsResult<JSValue> = 'brk: {
if let Some(err) = &self.err {
Expand Down
49 changes: 26 additions & 23 deletions src/runtime/node/node_fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use core::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use crate::api::bun::process::event_loop_handle_to_ctx;
use crate::webcore;
use bun_core::Environment;
use bun_core::{String as BunString, ZStr};
use bun_core::{OwnedString, String as BunString, ZStr};
use bun_event_loop::AnyTaskWithExtraContext::AnyTaskWithExtraContext;
use bun_io::KeepAlive;
use bun_jsc::AbortSignal;
Expand Down Expand Up @@ -1197,10 +1197,7 @@ mod _async_tasks {
impl FsReturn for ret::Readdir {
#[inline]
fn fs_to_js(&mut self, global: &JSGlobalObject) -> JsResult<JSValue> {
// `Readdir::to_js` consumes by value (the boxed slices are handed to
// JS). Swap in an empty `Files` payload so `&mut self` stays valid.
let owned = core::mem::replace(self, ret::Readdir::Files(Box::default()));
owned.to_js(global)
self.to_js(global)
}
}
impl FsReturn for StatOrNotFound {
Expand Down Expand Up @@ -2220,7 +2217,7 @@ mod _async_tasks {
}
}
} else {
let res = match core::mem::replace(
let mut res = match core::mem::replace(
&mut this.result_list,
ResultListEntryValue::Files(Vec::new()),
) {
Expand Down Expand Up @@ -4431,7 +4428,7 @@ impl StatOrNotFound {
}

pub enum StringOrUndefined {
String(BunString),
String(OwnedString),
None,
}
impl StringOrUndefined {
Expand Down Expand Up @@ -4508,43 +4505,49 @@ pub mod ret {
Files,
}

/// `to_js` converts in place; `Drop` releases whatever it did not hand over.
pub enum Readdir {
WithFileTypes(Box<[Dirent]>),
Buffers(Box<[Buffer]>),
Files(Box<[BunString]>),
}
impl Readdir {
pub fn to_js(self, global_object: &JSGlobalObject) -> JsResult<JSValue> {
pub fn to_js(&mut self, global_object: &JSGlobalObject) -> JsResult<JSValue> {
match self {
Readdir::WithFileTypes(mut items) => {
Readdir::WithFileTypes(items) => {
let array = JSValue::create_empty_array(global_object, items.len())?;
let mut previous_jsstring: *mut bun_jsc::JSString = core::ptr::null_mut();
for (i, item) in items.iter_mut().enumerate() {
let res =
item.to_js_newly_created(global_object, Some(&mut previous_jsstring))?;
array.put_index(global_object, i as u32, res)?;
}
// items dropped here (auto free)
Ok(array)
}
Readdir::Buffers(mut items) => {
Readdir::Buffers(items) => {
// Node returns `Buffer[]` for `{ encoding: "buffer" }`, not
// `Uint8Array[]`. Ownership of every `Buffer`'s bytes
// transfers to JSC via `to_node_buffer`; the boxed slice
// itself is freed when `items` drops.
// transfers to JSC via `to_node_buffer`.
let array = JSValue::create_empty_array(global_object, items.len())?;
for (i, item) in items.iter_mut().enumerate() {
let res = item.to_node_buffer(global_object)?;
array.put_index(global_object, i as u32, res)?;
}
Ok(array)
}
Readdir::Files(items) => {
// Converted to a JS array, then every element is
// deref'd and the slice freed (handled by the `FromAny
// for Box<[bun_core::String]>` impl).
JSValue::from_any(global_object, items)
}
// The array takes its own refs; ours go in `Drop`.
Readdir::Files(items) => bun_jsc::bun_string_jsc::to_js_array(global_object, items),
}
}
}
impl Drop for Readdir {
fn drop(&mut self) {
match self {
// Transferred entries are empty by now; `deref` on those is a no-op.
Readdir::WithFileTypes(items) => items.iter().for_each(Dirent::deref),
// `Buffer` frees whatever it still owns itself.
Readdir::Buffers(_) => {}
Readdir::Files(items) => items.iter().for_each(BunString::deref),
}
}
}
Expand Down Expand Up @@ -5711,8 +5714,8 @@ impl NodeFS {
if !RETURN_PATH {
return Ok(StringOrUndefined::None);
}
return Ok(StringOrUndefined::String(BunString::create_from_os_path(
&path[..],
return Ok(StringOrUndefined::String(OwnedString::new(
BunString::create_from_os_path(&path[..]),
)));
}
}
Expand Down Expand Up @@ -5881,8 +5884,8 @@ impl NodeFS {
if !RETURN_PATH {
return Ok(StringOrUndefined::None);
}
Ok(StringOrUndefined::String(BunString::create_from_os_path(
&working_mem[..first_match as usize],
Ok(StringOrUndefined::String(OwnedString::new(
BunString::create_from_os_path(&working_mem[..first_match as usize]),
)))
}

Expand Down
27 changes: 6 additions & 21 deletions src/runtime/webcore/Blob.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4634,26 +4634,16 @@ pub(crate) fn write_file_with_source_destination(
let source_type = source_store.data.tag();

if destination_type == store::DataTag::File && source_type == store::DataTag::Bytes {
let write_file_promise = bun_core::heap::into_raw(Box::new(WriteFilePromise {
promise: jsc::JSPromiseStrong::default(),
global_this: ctx,
}));

// The borrowed views below are +0 on the store ref;
// `WriteFile::create` takes its own ref.
#[cfg(windows)]
{
let promise = JSPromise::create(ctx);
let promise_value = promise.as_value(ctx);
let promise = WriteFilePromise::init(ctx);
let promise_value = promise.value();
promise_value.ensure_still_alive();
// SAFETY: write_file_promise was just produced by heap::alloc above; sole owner.
unsafe { (*write_file_promise).promise.set(ctx, promise_value) };
match write_file_mod::WriteFileWindows::create(
ctx.bun_vm().event_loop(),
destination_blob.borrowed_view(),
source_blob.borrowed_view(),
write_file_promise,
WriteFilePromise::run,
promise,
options.mkdirp_if_not_exists.unwrap_or(true),
) {
Err(write_file_mod::WriteFileWindowsError::WriteFileWindowsDeinitialized) => {}
Expand All @@ -4670,18 +4660,13 @@ pub(crate) fn write_file_with_source_destination(
let file_copier = write_file_mod::WriteFile::create(
destination_blob.borrowed_view(),
source_blob.borrowed_view(),
write_file_promise,
WriteFilePromise::run,
options.mkdirp_if_not_exists.unwrap_or(true),
)
.expect("unreachable");
// Defer promise creation until we're just about to schedule the task.
// SAFETY: write_file_promise was just produced by heap::alloc above; sole owner.
unsafe { (*write_file_promise).promise = jsc::JSPromiseStrong::init(ctx) };
// SAFETY: same `write_file_promise` as above; still solely owned here.
let promise_value = unsafe { (*write_file_promise).promise.value() };
let promise = WriteFilePromise::init(ctx);
let promise_value = promise.value();
promise_value.ensure_still_alive();
write_file_mod::WriteFile::schedule(file_copier, ctx);
write_file_mod::WriteFile::schedule(file_copier, promise, ctx);
return Ok(promise_value);
}
}
Expand Down
Loading