diff --git a/CMakeLists.txt b/CMakeLists.txt index c72a501415..f2b6f85f11 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_policy(SET CMP0067 NEW) set(CMAKE_POLICY_DEFAULT_CMP0069 NEW) set(Bun_VERSION "1.1.27") -set(WEBKIT_TAG 21fc366db3de8f30dbb7f5997b9b9f5cf422ff1e) +set(WEBKIT_TAG 3f9ba9bae0ee666f5e3edb295c86cbc855cd05a0) set(BUN_WORKDIR "${CMAKE_CURRENT_BINARY_DIR}") message(STATUS "Configuring Bun ${Bun_VERSION} in ${BUN_WORKDIR}") diff --git a/src/bun.js/bindings/ErrorCode.ts b/src/bun.js/bindings/ErrorCode.ts index 4118672c5f..9fcf1b0b2c 100644 --- a/src/bun.js/bindings/ErrorCode.ts +++ b/src/bun.js/bindings/ErrorCode.ts @@ -35,6 +35,7 @@ export default [ ["ERR_STREAM_WRITE_AFTER_END", TypeError, "TypeError"], ["ERR_ZLIB_INITIALIZATION_FAILED", TypeError, "TypeError"], ["ERR_STRING_TOO_LONG", Error, "Error"], + ["ERR_ILLEGAL_CONSTRUCTOR", TypeError, "TypeError"], // Bun-specific ["ERR_FORMDATA_PARSE_ERROR", TypeError, "TypeError"], diff --git a/src/bun.js/bindings/ProcessIdentifier.cpp b/src/bun.js/bindings/ProcessIdentifier.cpp index 5e82f4fe93..03e7342643 100644 --- a/src/bun.js/bindings/ProcessIdentifier.cpp +++ b/src/bun.js/bindings/ProcessIdentifier.cpp @@ -29,7 +29,7 @@ #include namespace WebCore { -namespace ProcessIdent { +namespace Process { static std::optional globalIdentifier; diff --git a/src/bun.js/bindings/ProcessIdentifier.h b/src/bun.js/bindings/ProcessIdentifier.h index e6141bdc05..1950d8cf0e 100644 --- a/src/bun.js/bindings/ProcessIdentifier.h +++ b/src/bun.js/bindings/ProcessIdentifier.h @@ -29,13 +29,13 @@ namespace WebCore { -enum ProcessIdentifierType {}; -using ProcessIdentifier = ObjectIdentifier; +enum class ProcessIdentifierType {}; +using ProcessIdentifier = LegacyNullableObjectIdentifier; -namespace ProcessIdent { +namespace Process { WEBCORE_EXPORT void setIdentifier(ProcessIdentifier); WEBCORE_EXPORT ProcessIdentifier identifier(); -} // namespace ProcessIdent +} // namespace Process } // namespace WebCore diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp index 0ac5486e58..78cf870c59 100644 --- a/src/bun.js/bindings/ZigGlobalObject.cpp +++ b/src/bun.js/bindings/ZigGlobalObject.cpp @@ -958,7 +958,7 @@ extern "C" bool Zig__GlobalObject__resetModuleRegistryMap(JSC__JSGlobalObject* g String GlobalObject::defaultAgentClusterID() { - return makeString(ProcessIdent::identifier().toUInt64(), "-default"_s); + return makeString(WebCore::Process::identifier().toUInt64(), "-default"_s); } String GlobalObject::agentClusterID() const diff --git a/src/bun.js/bindings/bindings.zig b/src/bun.js/bindings/bindings.zig index e45de5a035..b30bf74d80 100644 --- a/src/bun.js/bindings/bindings.zig +++ b/src/bun.js/bindings/bindings.zig @@ -3485,21 +3485,21 @@ pub const JSValue = enum(JSValueReprInt) { JSGenerator = 63, JSAsyncGenerator = 64, JSArrayIterator = 65, - JSMapIterator = 66, - JSSetIterator = 67, - JSStringIterator = 68, - JSPromise = 69, - JSMap = 70, - JSSet = 71, - JSWeakMap = 72, - JSWeakSet = 73, - WebAssemblyModule = 74, - WebAssemblyInstance = 75, - WebAssemblyGCObject = 76, - StringObject = 77, - DerivedStringObject = 78, - - InternalFieldTuple = 79, + JSIterator = 66, + JSMapIterator = 67, + JSSetIterator = 68, + JSStringIterator = 69, + JSPromise = 70, + JSMap = 71, + JSSet = 72, + JSWeakMap = 73, + JSWeakSet = 74, + WebAssemblyModule = 75, + WebAssemblyInstance = 76, + WebAssemblyGCObject = 77, + StringObject = 78, + DerivedStringObject = 79, + InternalFieldTuple = 80, MaxJS = 0b11111111, Event = 0b11101111, diff --git a/src/bun.js/bindings/webcore/EventTarget.cpp b/src/bun.js/bindings/webcore/EventTarget.cpp index 67bfb57cb5..1a859de05f 100644 --- a/src/bun.js/bindings/webcore/EventTarget.cpp +++ b/src/bun.js/bindings/webcore/EventTarget.cpp @@ -101,9 +101,9 @@ bool EventTarget::addEventListener(const AtomString& eventType, RefaddAlgorithm([weakThis = WeakPtr { *this }, eventType, listener = WeakPtr { listener }, capture = options.capture](JSC::JSValue value) { + options.signal->addAlgorithm([weakThis = WeakPtr { *this }, eventType, listener = WeakPtr { listener }, capture = options.capture](JSC::JSValue) { if (weakThis && listener) - weakThis->removeEventListener(eventType, *listener, capture); + Ref { *weakThis } -> removeEventListener(eventType, *listener, capture); }); } diff --git a/src/bun.js/bindings/webcore/JSDOMBuiltinConstructor.h b/src/bun.js/bindings/webcore/JSDOMBuiltinConstructor.h index 5c609b5abf..afd728ec6c 100644 --- a/src/bun.js/bindings/webcore/JSDOMBuiltinConstructor.h +++ b/src/bun.js/bindings/webcore/JSDOMBuiltinConstructor.h @@ -38,10 +38,11 @@ public: static JSC::JSValue prototypeForStructure(JSC::VM&, const JSDOMGlobalObject&); static JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES construct(JSC::JSGlobalObject*, JSC::CallFrame*); + static JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES call(JSC::JSGlobalObject*, JSC::CallFrame*); private: JSDOMBuiltinConstructor(JSC::VM& vm, JSC::Structure* structure) - : Base(vm, structure, construct) + : Base(vm, structure, construct, call) { } @@ -89,6 +90,25 @@ template inline JSC::Structure* JSDOMBuiltinConstructor inline JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSDOMBuiltinConstructor::call(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame) +{ + ASSERT(callFrame); + auto* castedThis = JSC::jsCast(callFrame->jsCallee()); + auto& vm = lexicalGlobalObject->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); + if (callFrame->thisValue() != castedThis) { + throwTypeError(lexicalGlobalObject, scope, "Constructor called as a function"_s); + return {}; + } + auto* structure = castedThis->getDOMStructureForJSObject(lexicalGlobalObject, asObject(callFrame->thisValue())); + if (UNLIKELY(!structure)) + return {}; + + auto* jsObject = JSClass::create(structure, castedThis->globalObject()); + JSC::call(lexicalGlobalObject, castedThis->initializeFunction(), jsObject, JSC::ArgList(callFrame), "This error should never occur: initialize function is guaranteed to be callable."_s); + return JSC::JSValue::encode(jsObject); +} + template inline JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSDOMBuiltinConstructor::construct(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame) { ASSERT(callFrame); diff --git a/src/bun.js/bindings/webcore/JSDOMBuiltinConstructorBase.h b/src/bun.js/bindings/webcore/JSDOMBuiltinConstructorBase.h index 9593d99c1c..8bcb43af7d 100644 --- a/src/bun.js/bindings/webcore/JSDOMBuiltinConstructorBase.h +++ b/src/bun.js/bindings/webcore/JSDOMBuiltinConstructorBase.h @@ -37,8 +37,8 @@ public: } protected: - JSDOMBuiltinConstructorBase(JSC::VM& vm, JSC::Structure* structure, JSC::NativeFunction functionForConstruct) - : Base(vm, structure, functionForConstruct) + JSDOMBuiltinConstructorBase(JSC::VM& vm, JSC::Structure* structure, JSC::NativeFunction functionForConstruct, JSC::NativeFunction functionForCall = nullptr) + : Base(vm, structure, functionForConstruct, functionForCall) { } diff --git a/src/bun.js/bindings/webcore/JSDOMConstructorBase.cpp b/src/bun.js/bindings/webcore/JSDOMConstructorBase.cpp index 76e5bed57d..09556cf5c9 100644 --- a/src/bun.js/bindings/webcore/JSDOMConstructorBase.cpp +++ b/src/bun.js/bindings/webcore/JSDOMConstructorBase.cpp @@ -20,29 +20,27 @@ */ #include "config.h" + #include "JSDOMConstructor.h" #include "WebCoreJSClientData.h" +#include "ErrorCode.h" namespace WebCore { using namespace JSC; STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSDOMConstructorBase); -JSC_DEFINE_HOST_FUNCTION(callThrowTypeErrorForJSDOMConstructor, (JSGlobalObject * globalObject, CallFrame*)) +JSC_DEFINE_HOST_FUNCTION(callThrowTypeErrorForJSDOMConstructor, (JSGlobalObject * globalObject, CallFrame* callframe)) { VM& vm = globalObject->vm(); auto scope = DECLARE_THROW_SCOPE(vm); - throwTypeError(globalObject, scope, "Constructor requires 'new' operator"_s); - return JSValue::encode(jsNull()); -} - -JSC_DEFINE_HOST_FUNCTION(callThrowTypeErrorForJSDOMConstructorNotConstructable, (JSC::JSGlobalObject * globalObject, JSC::CallFrame*)) -{ - JSC::VM& vm = globalObject->vm(); - auto scope = DECLARE_THROW_SCOPE(vm); - JSC::throwTypeError(globalObject, scope, "Illegal constructor"_s); - return JSC::JSValue::encode(JSC::jsNull()); + auto* callee = callframe->jsCallee(); + auto* constructor = jsDynamicCast(callee); + const auto& name = constructor->name(); + RETURN_IF_EXCEPTION(scope, {}); + Bun::throwError(globalObject, scope, Bun::ErrorCode::ERR_ILLEGAL_CONSTRUCTOR, makeString("Use `new "_s, name, "(...)` instead of `"_s, name, "(...)`"_s)); + return {}; } JSC::GCClient::IsoSubspace* JSDOMConstructorBase::subspaceForImpl(JSC::VM& vm) diff --git a/src/bun.js/bindings/webcore/JSDOMConstructorBase.h b/src/bun.js/bindings/webcore/JSDOMConstructorBase.h index 117ea9d39c..b8d16c1fe5 100644 --- a/src/bun.js/bindings/webcore/JSDOMConstructorBase.h +++ b/src/bun.js/bindings/webcore/JSDOMConstructorBase.h @@ -27,7 +27,6 @@ namespace WebCore { JSC_DECLARE_HOST_FUNCTION(callThrowTypeErrorForJSDOMConstructor); -JSC_DECLARE_HOST_FUNCTION(callThrowTypeErrorForJSDOMConstructorNotConstructable); // Base class for all callable constructor objects in the JSC bindings. class JSDOMConstructorBase : public JSC::InternalFunction { @@ -52,10 +51,10 @@ public: ScriptExecutionContext* scriptExecutionContext() const { return globalObject()->scriptExecutionContext(); } protected: - JSDOMConstructorBase(JSC::VM& vm, JSC::Structure* structure, JSC::NativeFunction functionForConstruct) + JSDOMConstructorBase(JSC::VM& vm, JSC::Structure* structure, JSC::NativeFunction functionForConstruct, JSC::NativeFunction functionForCall = nullptr) : Base(vm, structure, - functionForConstruct ? functionForConstruct : callThrowTypeErrorForJSDOMConstructorNotConstructable, - functionForConstruct ? functionForConstruct : callThrowTypeErrorForJSDOMConstructorNotConstructable) + functionForCall ? functionForCall : callThrowTypeErrorForJSDOMConstructor, + functionForConstruct ? functionForConstruct : callThrowTypeErrorForJSDOMConstructor) { } }; diff --git a/src/bun.js/bindings/webcore/MessageChannel.cpp b/src/bun.js/bindings/webcore/MessageChannel.cpp index 67407b9c04..e8928a3828 100644 --- a/src/bun.js/bindings/webcore/MessageChannel.cpp +++ b/src/bun.js/bindings/webcore/MessageChannel.cpp @@ -35,8 +35,8 @@ namespace WebCore { static std::pair, Ref> generateMessagePorts(ScriptExecutionContext& context) { - MessagePortIdentifier id1 = { ProcessIdent::identifier(), PortIdentifier::generate() }; - MessagePortIdentifier id2 = { ProcessIdent::identifier(), PortIdentifier::generate() }; + MessagePortIdentifier id1 = { WebCore::Process::identifier(), PortIdentifier::generate() }; + MessagePortIdentifier id2 = { WebCore::Process::identifier(), PortIdentifier::generate() }; return { MessagePort::create(context, id1, id2), MessagePort::create(context, id2, id1) }; } diff --git a/src/bun.js/bindings/webcore/MessagePort.cpp b/src/bun.js/bindings/webcore/MessagePort.cpp index a69728ad7f..aa05ebbbbb 100644 --- a/src/bun.js/bindings/webcore/MessagePort.cpp +++ b/src/bun.js/bindings/webcore/MessagePort.cpp @@ -141,7 +141,7 @@ MessagePort::MessagePort(ScriptExecutionContext& scriptExecutionContext, const M , m_identifier(local) , m_remoteIdentifier(remote) { - // LOG(MessagePorts, "Created MessagePort %s (%p) in process %" PRIu64, m_identifier.logString().utf8().data(), this, ProcessIdent::identifier().toUInt64()); + // LOG(MessagePorts, "Created MessagePort %s (%p) in process %" PRIu64, m_identifier.logString().utf8().data(), this, WebCore::Process::identifier().toUInt64()); Locker locker { allMessagePortsLock }; allMessagePorts().set(m_identifier, this); @@ -157,7 +157,7 @@ MessagePort::MessagePort(ScriptExecutionContext& scriptExecutionContext, const M MessagePort::~MessagePort() { - // LOG(MessagePorts, "Destroyed MessagePort %s (%p) in process %" PRIu64, m_identifier.logString().utf8().data(), this, ProcessIdent::identifier().toUInt64()); + // LOG(MessagePorts, "Destroyed MessagePort %s (%p) in process %" PRIu64, m_identifier.logString().utf8().data(), this, WebCore::Process::identifier().toUInt64()); ASSERT(allMessagePortsLock.isLocked()); diff --git a/src/bun.js/bindings/webcore/MessagePortChannelProviderImpl.cpp b/src/bun.js/bindings/webcore/MessagePortChannelProviderImpl.cpp index 0a21936a30..b569c0d18d 100644 --- a/src/bun.js/bindings/webcore/MessagePortChannelProviderImpl.cpp +++ b/src/bun.js/bindings/webcore/MessagePortChannelProviderImpl.cpp @@ -48,7 +48,7 @@ void MessagePortChannelProviderImpl::createNewMessagePortChannel(const MessagePo void MessagePortChannelProviderImpl::entangleLocalPortInThisProcessToRemote(const MessagePortIdentifier& local, const MessagePortIdentifier& remote) { - m_registry.didEntangleLocalToRemote(local, remote, ProcessIdent::identifier()); + m_registry.didEntangleLocalToRemote(local, remote, WebCore::Process::identifier()); } void MessagePortChannelProviderImpl::messagePortDisentangled(const MessagePortIdentifier& local) diff --git a/src/bun.js/bindings/webcore/MessagePortIdentifier.h b/src/bun.js/bindings/webcore/MessagePortIdentifier.h index eac8546de6..2d85e466a7 100644 --- a/src/bun.js/bindings/webcore/MessagePortIdentifier.h +++ b/src/bun.js/bindings/webcore/MessagePortIdentifier.h @@ -28,7 +28,7 @@ #include "PortIdentifier.h" #include "ProcessIdentifier.h" #include -#include +#include namespace WebCore { @@ -36,6 +36,8 @@ struct MessagePortIdentifier { ProcessIdentifier processIdentifier; PortIdentifier portIdentifier; + friend bool operator==(const MessagePortIdentifier&, const MessagePortIdentifier&) = default; + #if !LOG_DISABLED String logString() const; #endif @@ -46,11 +48,6 @@ inline void add(Hasher& hasher, const MessagePortIdentifier& identifier) add(hasher, identifier.processIdentifier, identifier.portIdentifier); } -inline bool operator==(const MessagePortIdentifier& a, const MessagePortIdentifier& b) -{ - return a.processIdentifier == b.processIdentifier && a.portIdentifier == b.portIdentifier; -} - #if !LOG_DISABLED inline String MessagePortIdentifier::logString() const diff --git a/src/bun.js/bindings/webcore/PortIdentifier.h b/src/bun.js/bindings/webcore/PortIdentifier.h index 8b77e792eb..17e9516d02 100644 --- a/src/bun.js/bindings/webcore/PortIdentifier.h +++ b/src/bun.js/bindings/webcore/PortIdentifier.h @@ -29,7 +29,7 @@ namespace WebCore { -enum PortIdentifierType {}; -using PortIdentifier = AtomicObjectIdentifier; +enum class PortIdentifierType {}; +using PortIdentifier = LegacyNullableAtomicObjectIdentifier; } diff --git a/test/js/web/websocket/websocket.test.js b/test/js/web/websocket/websocket.test.js index a550910d42..97b9308bc8 100644 --- a/test/js/web/websocket/websocket.test.js +++ b/test/js/web/websocket/websocket.test.js @@ -147,7 +147,7 @@ describe("WebSocket", () => { const url = `wss://127.0.0.1:${server.address.port}`; { // by default rejectUnauthorized is true - const client = WebSocket(url); + const client = new WebSocket(url); const { result, messages } = await testClient(client); expect(["Hello from Bun!", "Hello from client!"]).not.toEqual(messages); expect(result.code).toBe(1015); @@ -156,7 +156,7 @@ describe("WebSocket", () => { { // just in case we change the default to true and test - const client = WebSocket(url, { tls: { rejectUnauthorized: true } }); + const client = new WebSocket(url, { tls: { rejectUnauthorized: true } }); const { result, messages } = await testClient(client); expect(["Hello from Bun!", "Hello from client!"]).not.toEqual(messages); expect(result.code).toBe(1015); @@ -208,7 +208,7 @@ describe("WebSocket", () => { { // should allow self-signed certs when rejectUnauthorized is false - const client = WebSocket(url, { tls: { rejectUnauthorized: false } }); + const client = new WebSocket(url, { tls: { rejectUnauthorized: false } }); const { result, messages } = await testClient(client); expect(["Hello from Bun!", "Hello from client!"]).toEqual(messages); expect(result.code).toBe(1000); @@ -263,7 +263,7 @@ describe("WebSocket", () => { } const url = `wss://localhost:${server.address.port}`; { - const client = WebSocket(url); + const client = new WebSocket(url); const { result, messages } = await testClient(client); expect(["Hello from Bun!", "Hello from client!"]).not.toEqual(messages); expect(result.code).toBe(1015);