Compare commits

...

8 Commits

Author SHA1 Message Date
Jarred Sumner
3292f822d0 Merge branch 'main' into snoglobe/eventemitter_call 2024-12-09 21:00:12 -08:00
snwy
6b2a438f16 Merge branch 'main' into snoglobe/eventemitter_call 2024-12-09 13:16:06 -08:00
snwy
49d80755d6 test 2024-12-09 13:15:14 -08:00
Jarred Sumner
9b71264ab8 Merge branch 'main' into snoglobe/eventemitter_call 2024-12-08 09:36:56 -08:00
snwy
503154c1b3 undo suggestion 2024-12-05 17:00:12 -08:00
snoglobe
8e85cf4ae9 bun run clang-format 2024-12-06 00:52:53 +00:00
snwy
c54551e2ed Update src/bun.js/bindings/webcore/JSEventEmitter.cpp
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2024-12-05 16:51:23 -08:00
snwy
08fe4945f9 fix 2024-12-05 16:46:36 -08:00
3 changed files with 114 additions and 2 deletions

View File

@@ -0,0 +1,73 @@
/*
* Copyright (C) 2015, 2016 Canon Inc. All rights reserved.
* Copyright (C) 2016-2021 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include "JSDOMConstructorBase.h"
namespace WebCore {
template<typename JSClass> class JSDOMConstructorCallable final : public JSDOMConstructorBase {
public:
using Base = JSDOMConstructorBase;
static JSDOMConstructorCallable* create(JSC::VM&, JSC::Structure*, JSDOMGlobalObject&);
static JSC::Structure* createStructure(JSC::VM&, JSC::JSGlobalObject&, JSC::JSValue prototype);
DECLARE_INFO;
// Must be defined for each specialization class.
static JSC::JSValue prototypeForStructure(JSC::VM&, const JSDOMGlobalObject&);
// Must be defined for each specialization class.
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:
JSDOMConstructorCallable(JSC::VM& vm, JSC::Structure* structure)
: Base(vm, structure, construct, call)
{
}
void finishCreation(JSC::VM&, JSDOMGlobalObject&);
// Usually defined for each specialization class.
void initializeProperties(JSC::VM&, JSDOMGlobalObject&) {}
};
template<typename JSClass> inline JSDOMConstructorCallable<JSClass>* JSDOMConstructorCallable<JSClass>::create(JSC::VM& vm, JSC::Structure* structure, JSDOMGlobalObject& globalObject)
{
JSDOMConstructorCallable* constructor = new (NotNull, JSC::allocateCell<JSDOMConstructorCallable>(vm)) JSDOMConstructorCallable(vm, structure);
constructor->finishCreation(vm, globalObject);
return constructor;
}
template<typename JSClass> inline JSC::Structure* JSDOMConstructorCallable<JSClass>::createStructure(JSC::VM& vm, JSC::JSGlobalObject& globalObject, JSC::JSValue prototype)
{
return JSC::Structure::create(vm, &globalObject, prototype, JSC::TypeInfo(JSC::InternalFunctionType, StructureFlags), info());
}
template<typename JSClass> inline void JSDOMConstructorCallable<JSClass>::finishCreation(JSC::VM& vm, JSDOMGlobalObject& globalObject)
{
Base::finishCreation(vm);
ASSERT(inherits(info()));
initializeProperties(vm, globalObject);
}
} // namespace WebCore

View File

@@ -7,7 +7,7 @@
#include "IDLTypes.h"
#include "JSAddEventListenerOptions.h"
#include "JSDOMBinding.h"
#include "JSDOMConstructor.h"
#include "JSDOMConstructorCallable.h"
#include "JSDOMConvertBase.h"
#include "JSDOMConvertBoolean.h"
#include "JSDOMConvertDictionary.h"
@@ -94,7 +94,7 @@ public:
};
STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSEventEmitterPrototype, JSEventEmitterPrototype::Base);
using JSEventEmitterDOMConstructor = JSDOMConstructor<JSEventEmitter>;
using JSEventEmitterDOMConstructor = JSDOMConstructorCallable<JSEventEmitter>;
template<> JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSEventEmitterDOMConstructor::construct(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame)
{
@@ -124,6 +124,38 @@ template<> JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSEventEmitterDOMConstru
}
JSC_ANNOTATE_HOST_FUNCTION(JSEventEmitterDOMConstructorConstruct, JSEventEmitterDOMConstructor::construct);
template<> JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSEventEmitterDOMConstructor::call(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame)
{
VM& vm = lexicalGlobalObject->vm();
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto* castedThis = jsCast<JSEventEmitterDOMConstructor*>(callFrame->jsCallee());
ASSERT(castedThis);
auto* context = castedThis->scriptExecutionContext();
if (UNLIKELY(!context)) {
return throwConstructorScriptExecutionContextUnavailableError(*lexicalGlobalObject, throwScope, "EventEmitter"_s);
}
const auto object = EventEmitter::create(*context);
if constexpr (IsExceptionOr<decltype(object)>) {
RETURN_IF_EXCEPTION(throwScope, {});
}
JSValue maxListeners = castedThis->getIfPropertyExists(lexicalGlobalObject, JSC::Identifier::fromString(vm, "defaultMaxListeners"_s));
RETURN_IF_EXCEPTION(throwScope, {});
if (maxListeners && maxListeners.isUInt32()) {
object->setMaxListeners(maxListeners.toUInt32(lexicalGlobalObject));
}
static_assert(TypeOrExceptionOrUnderlyingType<decltype(object)>::isRef);
auto jsValue = toJSNewlyCreated<IDLInterface<EventEmitter>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, object.copyRef());
if constexpr (IsExceptionOr<decltype(object)>) {
RETURN_IF_EXCEPTION(throwScope, {});
}
Structure* structure = JSEventEmitter::createStructure(vm, lexicalGlobalObject, jsValue);
JSEventEmitter* instance
= JSEventEmitter::create(structure, reinterpret_cast<Zig::GlobalObject*>(lexicalGlobalObject), object.copyRef());
RETURN_IF_EXCEPTION(throwScope, {});
RELEASE_AND_RETURN(throwScope, JSValue::encode(instance));
}
JSC_ANNOTATE_HOST_FUNCTION(JSEventEmitterDOMConstructorCall, JSEventEmitterDOMConstructor::call);
template<> const ClassInfo JSEventEmitterDOMConstructor::s_info = { "EventEmitter"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSEventEmitterDOMConstructor) };
template<> JSValue JSEventEmitterDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)

View File

@@ -0,0 +1,7 @@
import { expect, test } from "bun:test";
import process from "process";
test("the constructor of process can be called", () => {
let obj = process.constructor.call({ ...process });
expect(Object.getPrototypeOf(obj)).toEqual(Object.getPrototypeOf(process));
});