aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bun.js/bindings/CallSite.cpp2
-rw-r--r--src/bun.js/bindings/CallSite.h3
-rw-r--r--src/bun.js/bindings/ErrorStackTrace.cpp2
-rw-r--r--src/bun.js/bindings/ErrorStackTrace.h2
-rw-r--r--src/bun.js/bindings/bindings.cpp4
-rw-r--r--src/bun.js/bindings/node_util_types.cpp35
-rw-r--r--src/bun.js/bindings/webcore/AbortSignal.cpp22
-rw-r--r--src/bun.js/bindings/webcore/AbortSignal.h4
-rw-r--r--src/bun.js/bindings/webcore/JSAbortSignalCustom.cpp1
-rw-r--r--src/bun.js/javascript.zig9
-rw-r--r--src/bun.js/node/node_fs.zig83
-rw-r--r--src/bun.js/readline.exports.js2
-rw-r--r--src/bun.js/test/jest.zig12
-rw-r--r--src/string_immutable.zig2
14 files changed, 153 insertions, 30 deletions
diff --git a/src/bun.js/bindings/CallSite.cpp b/src/bun.js/bindings/CallSite.cpp
index 522c6db1c..02ac35168 100644
--- a/src/bun.js/bindings/CallSite.cpp
+++ b/src/bun.js/bindings/CallSite.cpp
@@ -88,4 +88,4 @@ void CallSite::visitChildrenImpl(JSCell* cell, Visitor& visitor)
DEFINE_VISIT_CHILDREN(CallSite);
-} \ No newline at end of file
+}
diff --git a/src/bun.js/bindings/CallSite.h b/src/bun.js/bindings/CallSite.h
index efe1b39d8..fe6b8ef5e 100644
--- a/src/bun.js/bindings/CallSite.h
+++ b/src/bun.js/bindings/CallSite.h
@@ -81,6 +81,7 @@ private:
: Base(vm, structure)
, m_lineNumber(-1)
, m_columnNumber(-1)
+ , m_flags(0)
{
}
@@ -89,4 +90,4 @@ private:
DECLARE_VISIT_CHILDREN;
};
-} \ No newline at end of file
+}
diff --git a/src/bun.js/bindings/ErrorStackTrace.cpp b/src/bun.js/bindings/ErrorStackTrace.cpp
index dddaa31ea..59e0e765b 100644
--- a/src/bun.js/bindings/ErrorStackTrace.cpp
+++ b/src/bun.js/bindings/ErrorStackTrace.cpp
@@ -372,4 +372,4 @@ bool JSCStackFrame::calculateSourcePositions()
return true;
}
-} \ No newline at end of file
+}
diff --git a/src/bun.js/bindings/ErrorStackTrace.h b/src/bun.js/bindings/ErrorStackTrace.h
index 65ee60852..a8a6a192f 100644
--- a/src/bun.js/bindings/ErrorStackTrace.h
+++ b/src/bun.js/bindings/ErrorStackTrace.h
@@ -177,4 +177,4 @@ private:
}
};
-} \ No newline at end of file
+}
diff --git a/src/bun.js/bindings/bindings.cpp b/src/bun.js/bindings/bindings.cpp
index f43bfd4b8..7c1b3d82a 100644
--- a/src/bun.js/bindings/bindings.cpp
+++ b/src/bun.js/bindings/bindings.cpp
@@ -3961,7 +3961,7 @@ extern "C" bool WebCore__AbortSignal__aborted(WebCore__AbortSignal* arg0)
extern "C" JSC__JSValue WebCore__AbortSignal__abortReason(WebCore__AbortSignal* arg0)
{
WebCore::AbortSignal* abortSignal = reinterpret_cast<WebCore::AbortSignal*>(arg0);
- return JSC::JSValue::encode(abortSignal->reason().getValue());
+ return JSC::JSValue::encode(abortSignal->reason());
}
extern "C" WebCore__AbortSignal* WebCore__AbortSignal__ref(WebCore__AbortSignal* arg0)
@@ -3988,7 +3988,7 @@ extern "C" WebCore__AbortSignal* WebCore__AbortSignal__addListener(WebCore__Abor
WebCore::AbortSignal* abortSignal = reinterpret_cast<WebCore::AbortSignal*>(arg0);
if (abortSignal->aborted()) {
- callback(ctx, JSC::JSValue::encode(abortSignal->reason().getValue()));
+ callback(ctx, JSC::JSValue::encode(abortSignal->reason()));
return arg0;
}
diff --git a/src/bun.js/bindings/node_util_types.cpp b/src/bun.js/bindings/node_util_types.cpp
index bf135ed0b..d53cb1786 100644
--- a/src/bun.js/bindings/node_util_types.cpp
+++ b/src/bun.js/bindings/node_util_types.cpp
@@ -11,6 +11,7 @@
#include "JavaScriptCore/ObjectConstructor.h"
#include "JavaScriptCore/GeneratorFunctionPrototype.h"
#include "JavaScriptCore/AsyncFunctionPrototype.h"
+#include "JavaScriptCore/ErrorPrototype.h"
using namespace JSC;
@@ -84,7 +85,37 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionIsSymbolObject, (JSC::JSGlobalObject * global
JSC_DEFINE_HOST_FUNCTION(jsFunctionIsNativeError, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callframe))
{
GET_FIRST_VALUE
- return JSValue::encode(jsBoolean(value.isCell() && (value.inherits<JSC::ErrorInstance>() || value.asCell()->type() == ErrorInstanceType)));
+ if (value.isCell()) {
+ if (value.inherits<JSC::ErrorInstance>() || value.asCell()->type() == ErrorInstanceType)
+ return JSValue::encode(jsBoolean(true));
+
+ VM& vm = globalObject->vm();
+ auto scope = DECLARE_THROW_SCOPE(vm);
+ JSObject* object = value.toObject(globalObject);
+
+ // node util.isError relies on toString
+ // https://github.com/nodejs/node/blob/cf8c6994e0f764af02da4fa70bc5962142181bf3/doc/api/util.md#L2923
+ PropertySlot slot(object, PropertySlot::InternalMethodType::VMInquiry, &vm);
+ if (object->getPropertySlot(globalObject, vm.propertyNames->toStringTagSymbol, slot)) {
+ EXCEPTION_ASSERT(!scope.exception());
+ if (slot.isValue()) {
+ JSValue value = slot.getValue(globalObject, vm.propertyNames->toStringTagSymbol);
+ if (value.isString()) {
+ String tag = asString(value)->value(globalObject);
+ if (UNLIKELY(scope.exception()))
+ scope.clearException();
+ if (tag == "Error"_s)
+ return JSValue::encode(jsBoolean(true));
+ }
+ }
+ }
+
+ JSValue proto = object->getPrototype(vm, globalObject);
+ if (proto.isCell() && (proto.inherits<JSC::ErrorInstance>() || proto.asCell()->type() == ErrorInstanceType || proto.inherits<JSC::ErrorPrototype>()))
+ return JSValue::encode(jsBoolean(true));
+ }
+
+ return JSValue::encode(jsBoolean(false));
}
JSC_DEFINE_HOST_FUNCTION(jsFunctionIsRegExp, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callframe))
{
@@ -349,4 +380,4 @@ void generateNodeUtilTypesSourceCode(JSC::JSGlobalObject* lexicalGlobalObject,
exportNames.append(JSC::Identifier::fromString(vm, "default"_s));
exportValues.append(defaultObject);
}
-} \ No newline at end of file
+}
diff --git a/src/bun.js/bindings/webcore/AbortSignal.cpp b/src/bun.js/bindings/webcore/AbortSignal.cpp
index d20af5c81..febc610b7 100644
--- a/src/bun.js/bindings/webcore/AbortSignal.cpp
+++ b/src/bun.js/bindings/webcore/AbortSignal.cpp
@@ -78,7 +78,7 @@ Ref<AbortSignal> AbortSignal::timeout(ScriptExecutionContext& context, uint64_t
AbortSignal::AbortSignal(ScriptExecutionContext* context, Aborted aborted, JSC::JSValue reason)
: ContextDestructionObserver(context)
, m_aborted(aborted == Aborted::Yes)
- , m_reason(reason)
+ , m_reason(context->vm(), reason)
{
ASSERT(reason);
}
@@ -98,7 +98,8 @@ void AbortSignal::signalAbort(JSC::JSValue reason)
// FIXME: This code is wrong: we should emit a write-barrier. Otherwise, GC can collect it.
// https://bugs.webkit.org/show_bug.cgi?id=236353
ASSERT(reason);
- m_reason.setWeakly(reason);
+ auto& vm = scriptExecutionContext()->vm();
+ m_reason.set(vm, reason);
Ref protectedThis { *this };
auto algorithms = std::exchange(m_algorithms, {});
@@ -107,7 +108,7 @@ void AbortSignal::signalAbort(JSC::JSValue reason)
auto callbacks = std::exchange(m_native_callbacks, {});
for (auto callback : callbacks) {
- const auto [ ctx, func ] = callback;
+ const auto [ctx, func] = callback;
func(ctx, JSC::JSValue::encode(reason));
}
@@ -115,11 +116,12 @@ void AbortSignal::signalAbort(JSC::JSValue reason)
dispatchEvent(Event::create(eventNames().abortEvent, Event::CanBubble::No, Event::IsCancelable::No));
}
-void AbortSignal::cleanNativeBindings(void* ref) {
+void AbortSignal::cleanNativeBindings(void* ref)
+{
auto callbacks = std::exchange(m_native_callbacks, {});
- callbacks.removeAllMatching([=](auto callback){
- const auto [ ctx, func ] = callback;
+ callbacks.removeAllMatching([=](auto callback) {
+ const auto [ctx, func] = callback;
return ctx == ref;
});
}
@@ -131,7 +133,7 @@ void AbortSignal::signalFollow(AbortSignal& signal)
return;
if (signal.aborted()) {
- signalAbort(signal.reason().getValue());
+ signalAbort(signal.reason());
return;
}
@@ -140,7 +142,7 @@ void AbortSignal::signalFollow(AbortSignal& signal)
signal.addAlgorithm([weakThis = WeakPtr { this }](JSC::JSValue reason) {
if (weakThis) {
if (reason.isEmpty() || reason.isUndefined()) {
- weakThis->signalAbort(weakThis->m_followingSignal ? weakThis->m_followingSignal->reason().getValue()
+ weakThis->signalAbort(weakThis->m_followingSignal ? weakThis->m_followingSignal->reason()
: JSC::jsUndefined());
} else {
weakThis->signalAbort(reason);
@@ -157,7 +159,7 @@ void AbortSignal::eventListenersDidChange()
bool AbortSignal::whenSignalAborted(AbortSignal& signal, Ref<AbortAlgorithm>&& algorithm)
{
if (signal.aborted()) {
- algorithm->handleEvent(signal.m_reason.getValue());
+ algorithm->handleEvent(signal.m_reason.get());
return true;
}
signal.addAlgorithm([algorithm = WTFMove(algorithm)](JSC::JSValue value) mutable {
@@ -173,7 +175,7 @@ void AbortSignal::throwIfAborted(JSC::JSGlobalObject& lexicalGlobalObject)
auto& vm = lexicalGlobalObject.vm();
auto scope = DECLARE_THROW_SCOPE(vm);
- throwException(&lexicalGlobalObject, scope, m_reason.getValue());
+ throwException(&lexicalGlobalObject, scope, m_reason.get());
}
} // namespace WebCore
diff --git a/src/bun.js/bindings/webcore/AbortSignal.h b/src/bun.js/bindings/webcore/AbortSignal.h
index 03374b248..6f4abf5ba 100644
--- a/src/bun.js/bindings/webcore/AbortSignal.h
+++ b/src/bun.js/bindings/webcore/AbortSignal.h
@@ -55,7 +55,7 @@ public:
void signalFollow(AbortSignal&);
bool aborted() const { return m_aborted; }
- const JSValueInWrappedObject& reason() const { return m_reason; }
+ JSValue reason() const { return m_reason.get(); }
bool hasActiveTimeoutTimer() const { return m_hasActiveTimeoutTimer; }
bool hasAbortEventListener() const { return m_hasAbortEventListener; }
@@ -90,7 +90,7 @@ private:
Vector<Algorithm> m_algorithms;
Vector<std::tuple<void*, void (*)(void*, JSC::EncodedJSValue)>> m_native_callbacks;
WeakPtr<AbortSignal> m_followingSignal;
- JSValueInWrappedObject m_reason;
+ JSC::Strong<JSC::Unknown> m_reason;
bool m_hasActiveTimeoutTimer { false };
bool m_hasAbortEventListener { false };
};
diff --git a/src/bun.js/bindings/webcore/JSAbortSignalCustom.cpp b/src/bun.js/bindings/webcore/JSAbortSignalCustom.cpp
index bc3bab081..88a94c7c0 100644
--- a/src/bun.js/bindings/webcore/JSAbortSignalCustom.cpp
+++ b/src/bun.js/bindings/webcore/JSAbortSignalCustom.cpp
@@ -54,7 +54,6 @@ bool JSAbortSignalOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> ha
template<typename Visitor>
void JSAbortSignal::visitAdditionalChildren(Visitor& visitor)
{
- wrapped().reason().visit(visitor);
}
DEFINE_VISIT_ADDITIONAL_CHILDREN(JSAbortSignal);
diff --git a/src/bun.js/javascript.zig b/src/bun.js/javascript.zig
index f54dd5fb8..3841a07e2 100644
--- a/src/bun.js/javascript.zig
+++ b/src/bun.js/javascript.zig
@@ -362,6 +362,7 @@ pub const VirtualMachine = struct {
uws_event_loop: ?*uws.Loop = null,
pending_unref_counter: i32 = 0,
preload: []const string = &[_][]const u8{},
+ unhandled_pending_rejection_to_capture: ?*JSC.JSValue = null,
/// hide bun:wrap from stack traces
/// bun:wrap is very noisy
@@ -479,6 +480,14 @@ pub const VirtualMachine = struct {
this.unhandled_error_counter += 1;
}
+ pub fn onQuietUnhandledRejectionHandlerCaptureValue(this: *VirtualMachine, _: *JSC.JSGlobalObject, value: JSC.JSValue) void {
+ this.unhandled_error_counter += 1;
+ value.ensureStillAlive();
+ if (this.unhandled_pending_rejection_to_capture) |ptr| {
+ ptr.* = value;
+ }
+ }
+
pub fn unhandledRejectionScope(this: *VirtualMachine) UnhandledRejectionScope {
return .{
.onUnhandledRejection = this.onUnhandledRejection,
diff --git a/src/bun.js/node/node_fs.zig b/src/bun.js/node/node_fs.zig
index e068349a8..845992ecc 100644
--- a/src/bun.js/node/node_fs.zig
+++ b/src/bun.js/node/node_fs.zig
@@ -3582,8 +3582,82 @@ pub const NodeFS = struct {
pub fn rmdir(this: *NodeFS, args: Arguments.RmDir, comptime flavor: Flavor) Maybe(Return.Rmdir) {
switch (comptime flavor) {
.sync => {
- return Maybe(Return.Rmdir).errnoSysP(system.rmdir(args.path.sliceZ(&this.sync_error_buf)), .rmdir, args.path.slice()) orelse
- Maybe(Return.Rmdir).success;
+ if (comptime Environment.isMac) {
+ if (args.recursive) {
+ var dest = args.path.sliceZ(&this.sync_error_buf);
+
+ var flags: u32 = bun.C.darwin.RemoveFileFlags.cross_mount |
+ bun.C.darwin.RemoveFileFlags.allow_long_paths |
+ bun.C.darwin.RemoveFileFlags.recursive;
+
+ while (true) {
+ if (Maybe(Return.Rmdir).errnoSys(bun.C.darwin.removefileat(std.os.AT.FDCWD, dest, null, flags), .rmdir)) |errno| {
+ switch (@intToEnum(os.E, errno.err.errno)) {
+ .AGAIN, .INTR => continue,
+ .NOENT => return Maybe(Return.Rmdir).success,
+ .MLINK => {
+ var copy: [bun.MAX_PATH_BYTES]u8 = undefined;
+ @memcpy(&copy, dest.ptr, dest.len);
+ copy[dest.len] = 0;
+ var dest_copy = copy[0..dest.len :0];
+ switch (Syscall.unlink(dest_copy).getErrno()) {
+ .AGAIN, .INTR => continue,
+ .NOENT => return errno,
+ .SUCCESS => continue,
+ else => return errno,
+ }
+ },
+ .SUCCESS => unreachable,
+ else => return errno,
+ }
+ }
+
+ return Maybe(Return.Rmdir).success;
+ }
+ }
+
+ return Maybe(Return.Rmdir).errnoSysP(system.rmdir(args.path.sliceZ(&this.sync_error_buf)), .rmdir, args.path.slice()) orelse
+ Maybe(Return.Rmdir).success;
+ } else if (comptime Environment.isLinux) {
+ if (args.recursive) {
+ std.fs.cwd().deleteTree(args.path.slice()) catch |err| {
+ const errno: std.os.E = switch (err) {
+ error.InvalidHandle => .BADF,
+ error.AccessDenied => .PERM,
+ error.FileTooBig => .FBIG,
+ error.SymLinkLoop => .LOOP,
+ error.ProcessFdQuotaExceeded => .NFILE,
+ error.NameTooLong => .NAMETOOLONG,
+ error.SystemFdQuotaExceeded => .MFILE,
+ error.SystemResources => .NOMEM,
+ error.ReadOnlyFileSystem => .ROFS,
+ error.FileSystem => .IO,
+ error.FileBusy => .BUSY,
+ error.DeviceBusy => .BUSY,
+
+ // One of the path components was not a directory.
+ // This error is unreachable if `sub_path` does not contain a path separator.
+ error.NotDir => .NOTDIR,
+ // On Windows, file paths must be valid Unicode.
+ error.InvalidUtf8 => .INVAL,
+
+ // On Windows, file paths cannot contain these characters:
+ // '/', '*', '?', '"', '<', '>', '|'
+ error.BadPathName => .INVAL,
+
+ else => .FAULT,
+ };
+ return Maybe(Return.Rm){
+ .err = JSC.Node.Syscall.Error.fromCode(errno, .rmdir),
+ };
+ };
+
+ return Maybe(Return.Rmdir).success;
+ }
+
+ return Maybe(Return.Rmdir).errnoSysP(system.rmdir(args.path.sliceZ(&this.sync_error_buf)), .rmdir, args.path.slice()) orelse
+ Maybe(Return.Rmdir).success;
+ }
},
else => {},
}
@@ -3685,9 +3759,8 @@ pub const NodeFS = struct {
std.os.unlinkZ(dest) catch |er| {
// empircally, it seems to return AccessDenied when the
// file is actually a directory on macOS.
- if (er == error.IsDir or
- er == error.NotDir or
- er == error.AccessDenied)
+ if (args.recursive and
+ (er == error.IsDir or er == error.NotDir or er == error.AccessDenied))
{
std.os.rmdirZ(dest) catch |err| {
if (args.force) {
diff --git a/src/bun.js/readline.exports.js b/src/bun.js/readline.exports.js
index be7b75568..3044c5c20 100644
--- a/src/bun.js/readline.exports.js
+++ b/src/bun.js/readline.exports.js
@@ -2248,7 +2248,7 @@ var _Interface = class Interface extends InterfaceConstructor {
var previousKey = this[kPreviousKey];
key = key || kEmptyObject;
this[kPreviousKey] = key;
- var { name: keyName, meta: keyMeta, ctrl: keyCtrl, shift: keyShift } = key;
+ var { name: keyName, meta: keyMeta, ctrl: keyCtrl, shift: keyShift, sequence: keySeq } = key;
if (!keyMeta || keyName !== "y") {
// Reset yanking state unless we are doing yank pop.
diff --git a/src/bun.js/test/jest.zig b/src/bun.js/test/jest.zig
index 7aebf7e66..963a13967 100644
--- a/src/bun.js/test/jest.zig
+++ b/src/bun.js/test/jest.zig
@@ -2126,9 +2126,17 @@ pub const Expect = struct {
const result_: ?JSValue = brk: {
var vm = globalObject.bunVM();
+ var return_value: JSValue = .zero;
var scope = vm.unhandledRejectionScope();
- vm.onUnhandledRejection = &VirtualMachine.onQuietUnhandledRejectionHandler;
- const return_value: JSValue = value.call(globalObject, &.{});
+ var prev_unhandled_pending_rejection_to_capture = vm.unhandled_pending_rejection_to_capture;
+ vm.unhandled_pending_rejection_to_capture = &return_value;
+ vm.onUnhandledRejection = &VirtualMachine.onQuietUnhandledRejectionHandlerCaptureValue;
+ const return_value_from_fucntion: JSValue = value.call(globalObject, &.{});
+ vm.unhandled_pending_rejection_to_capture = prev_unhandled_pending_rejection_to_capture;
+
+ if (return_value == .zero) {
+ return_value = return_value_from_fucntion;
+ }
if (return_value.asAnyPromise()) |promise| {
globalObject.bunVM().waitForPromise(promise);
diff --git a/src/string_immutable.zig b/src/string_immutable.zig
index 321abb9f7..f4c6fae07 100644
--- a/src/string_immutable.zig
+++ b/src/string_immutable.zig
@@ -2146,7 +2146,7 @@ pub fn escapeHTMLForLatin1Input(allocator: std.mem.Allocator, latin1: []const u8
buf = try std.ArrayList(u8).initCapacity(allocator, latin1.len + @as(usize, Scalar.lengths[c]));
const copy_len = @ptrToInt(ptr) - @ptrToInt(latin1.ptr);
- @memcpy(buf.items.ptr, latin1.ptr, copy_len - 1);
+ @memcpy(buf.items.ptr, latin1.ptr, copy_len);
buf.items.len = copy_len;
any_needs_escape = true;
break :scan_and_allocate_lazily;