mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 15:08:46 +00:00
Fix WriteBarrier initialization to use WriteBarrierEarlyInit (#23435)
## Summary
This PR fixes incorrect WriteBarrier initialization patterns throughout
the Bun codebase where `.set()` or `.setEarlyValue()` was being called
in the constructor body or in `finishCreation()`. According to
JavaScriptCore's `WriteBarrier.h`, WriteBarriers that are initialized
during construction should use the `WriteBarrierEarlyInit` constructor
in the initializer list to avoid triggering unnecessary write barriers.
## Changes
The following classes were updated to properly initialize WriteBarrier
fields:
1. **InternalModuleRegistry** - Initialize internal fields in
constructor using `setWithoutWriteBarrier()` instead of calling `.set()`
in `finishCreation()`
2. **AsyncContextFrame** - Pass callback and context to constructor and
use `WriteBarrierEarlyInit`
3. **JSCommonJSModule** - Pass id, filename, dirname to constructor and
use `WriteBarrierEarlyInit`
4. **JSMockImplementation** - Pass initial values to constructor and use
`WriteBarrierEarlyInit`
5. **JSConnectionsList** - Pass connection sets to constructor and use
`WriteBarrierEarlyInit`
6. **JSBunRequest** - Pass params to constructor and initialize both
`m_params` and `m_cookies` using `WriteBarrierEarlyInit`
7. **JSNodeHTTPServerSocket** - Initialize `currentResponseObject` using
`WriteBarrierEarlyInit` instead of calling `setEarlyValue()`
## Why This Matters
From JavaScriptCore's `WriteBarrier.h`:
```cpp
enum WriteBarrierEarlyInitTag { WriteBarrierEarlyInit };
// Constructor for early initialization during object construction
WriteBarrier(T* value, WriteBarrierEarlyInitTag)
{
this->setWithoutWriteBarrier(value);
}
```
Using `WriteBarrierEarlyInit` during construction:
- Avoids triggering write barriers when they're not needed
- Is the correct pattern for initializing WriteBarriers before the
object is fully constructed
- Aligns with JavaScriptCore best practices
## Testing
- ✅ Full debug build completes successfully
- ✅ Basic functionality tested (CommonJS modules, HTTP requests, Node
HTTP servers)
- ✅ No regressions observed
## Note on generate-classes.ts
The code generator (`generate-classes.ts`) does not need updates because
generated classes intentionally leave WriteBarrier fields (callbacks,
cached fields, values) uninitialized. They start with
default-constructed WriteBarriers and are populated later by Zig code
via setter functions, which is the correct pattern for those fields.
---------
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -14,10 +14,8 @@ const ClassInfo AsyncContextFrame::s_info = { "AsyncContextFrame"_s, &Base::s_in
|
||||
|
||||
AsyncContextFrame* AsyncContextFrame::create(VM& vm, JSC::Structure* structure, JSValue callback, JSValue context)
|
||||
{
|
||||
AsyncContextFrame* asyncContextData = new (NotNull, allocateCell<AsyncContextFrame>(vm)) AsyncContextFrame(vm, structure);
|
||||
AsyncContextFrame* asyncContextData = new (NotNull, allocateCell<AsyncContextFrame>(vm)) AsyncContextFrame(vm, structure, callback, context);
|
||||
asyncContextData->finishCreation(vm);
|
||||
asyncContextData->callback.set(vm, asyncContextData, callback);
|
||||
asyncContextData->context.set(vm, asyncContextData, context);
|
||||
return asyncContextData;
|
||||
}
|
||||
|
||||
@@ -26,10 +24,8 @@ AsyncContextFrame* AsyncContextFrame::create(JSGlobalObject* global, JSValue cal
|
||||
auto& vm = global->vm();
|
||||
ASSERT(callback.isCallable());
|
||||
auto* structure = jsCast<Zig::GlobalObject*>(global)->AsyncContextFrameStructure();
|
||||
AsyncContextFrame* asyncContextData = new (NotNull, allocateCell<AsyncContextFrame>(vm)) AsyncContextFrame(vm, structure);
|
||||
AsyncContextFrame* asyncContextData = new (NotNull, allocateCell<AsyncContextFrame>(vm)) AsyncContextFrame(vm, structure, callback, context);
|
||||
asyncContextData->finishCreation(vm);
|
||||
asyncContextData->callback.set(vm, asyncContextData, callback);
|
||||
asyncContextData->context.set(vm, asyncContextData, context);
|
||||
return asyncContextData;
|
||||
}
|
||||
|
||||
|
||||
@@ -57,8 +57,10 @@ public:
|
||||
[](auto& spaces, auto&& space) { spaces.m_subspaceForAsyncContextFrame = std::forward<decltype(space)>(space); });
|
||||
}
|
||||
|
||||
AsyncContextFrame(JSC::VM& vm, JSC::Structure* structure)
|
||||
AsyncContextFrame(JSC::VM& vm, JSC::Structure* structure, JSC::JSValue callback_, JSC::JSValue context_)
|
||||
: JSNonFinalObject(vm, structure)
|
||||
, callback(callback_, JSC::WriteBarrierEarlyInit)
|
||||
, context(context_, JSC::WriteBarrierEarlyInit)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
@@ -426,29 +426,29 @@ public:
|
||||
[](auto& spaces, auto&& space) { spaces.m_subspaceForJSModuleMock = std::forward<decltype(space)>(space); });
|
||||
}
|
||||
|
||||
void finishCreation(JSC::VM&, JSC::JSObject* callback);
|
||||
void finishCreation(JSC::VM&);
|
||||
|
||||
private:
|
||||
JSModuleMock(JSC::VM&, JSC::Structure*);
|
||||
JSModuleMock(JSC::VM&, JSC::Structure*, JSC::JSObject* callback);
|
||||
};
|
||||
|
||||
const JSC::ClassInfo JSModuleMock::s_info = { "ModuleMock"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSModuleMock) };
|
||||
|
||||
JSModuleMock* JSModuleMock::create(JSC::VM& vm, JSC::Structure* structure, JSC::JSObject* callback)
|
||||
{
|
||||
JSModuleMock* ptr = new (NotNull, JSC::allocateCell<JSModuleMock>(vm)) JSModuleMock(vm, structure);
|
||||
ptr->finishCreation(vm, callback);
|
||||
JSModuleMock* ptr = new (NotNull, JSC::allocateCell<JSModuleMock>(vm)) JSModuleMock(vm, structure, callback);
|
||||
ptr->finishCreation(vm);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void JSModuleMock::finishCreation(JSC::VM& vm, JSObject* callback)
|
||||
void JSModuleMock::finishCreation(JSC::VM& vm)
|
||||
{
|
||||
Base::finishCreation(vm);
|
||||
callbackFunctionOrCachedResult.set(vm, this, callback);
|
||||
}
|
||||
|
||||
JSModuleMock::JSModuleMock(JSC::VM& vm, JSC::Structure* structure)
|
||||
JSModuleMock::JSModuleMock(JSC::VM& vm, JSC::Structure* structure, JSC::JSObject* callback)
|
||||
: Base(vm, structure)
|
||||
, callbackFunctionOrCachedResult(callback, JSC::WriteBarrierEarlyInit)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -124,6 +124,11 @@ const ClassInfo InternalModuleRegistry::s_info = { "InternalModuleRegistry"_s, &
|
||||
InternalModuleRegistry::InternalModuleRegistry(VM& vm, Structure* structure)
|
||||
: Base(vm, structure)
|
||||
{
|
||||
// Initialize all internal fields to jsUndefined() using setWithoutWriteBarrier
|
||||
// to avoid triggering write barriers during construction
|
||||
for (uint8_t i = 0; i < BUN_INTERNAL_MODULE_COUNT; i++) {
|
||||
this->internalField(static_cast<Field>(i)).setWithoutWriteBarrier(jsUndefined());
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Visitor>
|
||||
@@ -147,10 +152,6 @@ void InternalModuleRegistry::finishCreation(VM& vm)
|
||||
{
|
||||
Base::finishCreation(vm);
|
||||
ASSERT(inherits(info()));
|
||||
|
||||
for (uint8_t i = 0; i < BUN_INTERNAL_MODULE_COUNT; i++) {
|
||||
this->internalField(static_cast<Field>(i)).set(vm, this, jsUndefined());
|
||||
}
|
||||
}
|
||||
|
||||
Structure* InternalModuleRegistry::createStructure(VM& vm, JSGlobalObject* globalObject)
|
||||
|
||||
@@ -58,8 +58,8 @@ JSBunRequest* JSBunRequest::create(JSC::VM& vm, JSC::Structure* structure, void*
|
||||
// We do not want to risk the GC running before this function is called.
|
||||
Bun__JSRequest__calculateEstimatedByteSize(sinkPtr);
|
||||
|
||||
JSBunRequest* ptr = new (NotNull, JSC::allocateCell<JSBunRequest>(vm)) JSBunRequest(vm, structure, sinkPtr);
|
||||
ptr->finishCreation(vm, params);
|
||||
JSBunRequest* ptr = new (NotNull, JSC::allocateCell<JSBunRequest>(vm)) JSBunRequest(vm, structure, sinkPtr, params);
|
||||
ptr->finishCreation(vm);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@@ -148,17 +148,17 @@ void JSBunRequest::setCookies(JSObject* cookies)
|
||||
Request__setCookiesOnRequestContext(this->wrapped(), WebCoreCast<WebCore::JSCookieMap, WebCore::CookieMap>(JSValue::encode(cookies)));
|
||||
}
|
||||
|
||||
JSBunRequest::JSBunRequest(JSC::VM& vm, JSC::Structure* structure, void* sinkPtr)
|
||||
JSBunRequest::JSBunRequest(JSC::VM& vm, JSC::Structure* structure, void* sinkPtr, JSC::JSObject* params)
|
||||
: Base(vm, structure, sinkPtr)
|
||||
, m_params(params, JSC::WriteBarrierEarlyInit)
|
||||
, m_cookies(nullptr, JSC::WriteBarrierEarlyInit)
|
||||
{
|
||||
}
|
||||
extern SYSV_ABI "C" size_t Request__estimatedSize(void* requestPtr);
|
||||
extern "C" void Bun__JSRequest__calculateEstimatedByteSize(void* requestPtr);
|
||||
void JSBunRequest::finishCreation(JSC::VM& vm, JSObject* params)
|
||||
void JSBunRequest::finishCreation(JSC::VM& vm)
|
||||
{
|
||||
Base::finishCreation(vm);
|
||||
m_params.setMayBeNull(vm, this, params);
|
||||
m_cookies.clear();
|
||||
|
||||
auto size = Request__estimatedSize(this->wrapped());
|
||||
vm.heap.reportExtraMemoryAllocated(this, size);
|
||||
|
||||
@@ -39,8 +39,8 @@ public:
|
||||
JSBunRequest* clone(JSC::VM& vm, JSGlobalObject* globalObject);
|
||||
|
||||
private:
|
||||
JSBunRequest(JSC::VM& vm, JSC::Structure* structure, void* sinkPtr);
|
||||
void finishCreation(JSC::VM& vm, JSObject* params);
|
||||
JSBunRequest(JSC::VM& vm, JSC::Structure* structure, void* sinkPtr, JSC::JSObject* params);
|
||||
void finishCreation(JSC::VM& vm);
|
||||
|
||||
mutable JSC::WriteBarrier<JSC::JSObject> m_params;
|
||||
mutable JSC::WriteBarrier<JSC::JSObject> m_cookies;
|
||||
|
||||
@@ -817,13 +817,10 @@ public:
|
||||
|
||||
const JSC::ClassInfo JSCommonJSModulePrototype::s_info = { "Module"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSCommonJSModulePrototype) };
|
||||
|
||||
void JSCommonJSModule::finishCreation(JSC::VM& vm, JSC::JSString* id, JSValue filename, JSC::JSString* dirname, const JSC::SourceCode& sourceCode)
|
||||
void JSCommonJSModule::finishCreation(JSC::VM& vm, const JSC::SourceCode& sourceCode)
|
||||
{
|
||||
Base::finishCreation(vm);
|
||||
ASSERT(inherits(info()));
|
||||
m_id.set(vm, this, id);
|
||||
m_filename.set(vm, this, filename);
|
||||
m_dirname.set(vm, this, dirname);
|
||||
this->sourceCode = sourceCode;
|
||||
}
|
||||
|
||||
@@ -847,8 +844,8 @@ JSCommonJSModule* JSCommonJSModule::create(
|
||||
JSC::JSString* dirname,
|
||||
const JSC::SourceCode& sourceCode)
|
||||
{
|
||||
JSCommonJSModule* cell = new (NotNull, JSC::allocateCell<JSCommonJSModule>(vm)) JSCommonJSModule(vm, structure);
|
||||
cell->finishCreation(vm, id, filename, dirname, sourceCode);
|
||||
JSCommonJSModule* cell = new (NotNull, JSC::allocateCell<JSCommonJSModule>(vm)) JSCommonJSModule(vm, structure, id, filename, dirname);
|
||||
cell->finishCreation(vm, sourceCode);
|
||||
return cell;
|
||||
}
|
||||
|
||||
|
||||
@@ -83,9 +83,7 @@ public:
|
||||
|
||||
void clearSourceCode() { sourceCode = JSC::SourceCode(); }
|
||||
|
||||
void finishCreation(JSC::VM& vm,
|
||||
JSC::JSString* id, JSValue filename,
|
||||
JSC::JSString* dirname, const JSC::SourceCode& sourceCode);
|
||||
void finishCreation(JSC::VM& vm, const JSC::SourceCode& sourceCode);
|
||||
|
||||
static JSC::Structure* createStructure(JSC::JSGlobalObject* globalObject);
|
||||
|
||||
@@ -153,8 +151,11 @@ public:
|
||||
|
||||
bool hasEvaluated = false;
|
||||
|
||||
JSCommonJSModule(JSC::VM& vm, JSC::Structure* structure)
|
||||
JSCommonJSModule(JSC::VM& vm, JSC::Structure* structure, JSC::JSString* id, JSC::JSValue filename, JSC::JSString* dirname)
|
||||
: Base(vm, structure)
|
||||
, m_id(id, JSC::WriteBarrierEarlyInit)
|
||||
, m_filename(filename, JSC::WriteBarrierEarlyInit)
|
||||
, m_dirname(dirname, JSC::WriteBarrierEarlyInit)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
@@ -154,8 +154,8 @@ public:
|
||||
static JSMockImplementation* create(JSC::JSGlobalObject* globalObject, JSC::Structure* structure, Kind kind, JSC::JSValue heldValue, bool isOnce)
|
||||
{
|
||||
auto& vm = JSC::getVM(globalObject);
|
||||
JSMockImplementation* impl = new (NotNull, allocateCell<JSMockImplementation>(vm)) JSMockImplementation(vm, structure, kind);
|
||||
impl->finishCreation(vm, heldValue, isOnce ? jsNumber(1) : jsUndefined());
|
||||
JSMockImplementation* impl = new (NotNull, allocateCell<JSMockImplementation>(vm)) JSMockImplementation(vm, structure, kind, heldValue, isOnce ? jsNumber(1) : jsUndefined());
|
||||
impl->finishCreation(vm);
|
||||
return impl;
|
||||
}
|
||||
|
||||
@@ -195,17 +195,17 @@ public:
|
||||
return !nextValueOrSentinel.get().isUndefined();
|
||||
}
|
||||
|
||||
JSMockImplementation(JSC::VM& vm, JSC::Structure* structure, Kind kind)
|
||||
JSMockImplementation(JSC::VM& vm, JSC::Structure* structure, Kind kind, JSC::JSValue first, JSC::JSValue second)
|
||||
: Base(vm, structure)
|
||||
, underlyingValue(first, JSC::WriteBarrierEarlyInit)
|
||||
, nextValueOrSentinel(second, JSC::WriteBarrierEarlyInit)
|
||||
, kind(kind)
|
||||
{
|
||||
}
|
||||
|
||||
void finishCreation(JSC::VM& vm, JSC::JSValue first, JSC::JSValue second)
|
||||
void finishCreation(JSC::VM& vm)
|
||||
{
|
||||
Base::finishCreation(vm);
|
||||
this->underlyingValue.set(vm, this, first);
|
||||
this->nextValueOrSentinel.set(vm, this, second);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -33,12 +33,10 @@ JS_EXPORT_PRIVATE JSWrappingFunction* JSWrappingFunction::create(
|
||||
|
||||
// Structure* structure = globalObject->FFIFunctionStructure();
|
||||
Structure* structure = JSWrappingFunction::createStructure(vm, globalObject, globalObject->objectPrototype());
|
||||
JSWrappingFunction* function = new (NotNull, allocateCell<JSWrappingFunction>(vm)) JSWrappingFunction(vm, executable, globalObject, structure);
|
||||
JSWrappingFunction* function = new (NotNull, allocateCell<JSWrappingFunction>(vm)) JSWrappingFunction(vm, executable, globalObject, structure, wrappedFn);
|
||||
ASSERT(function->structure()->globalObject());
|
||||
function->finishCreation(vm, executable, 0, nameStr);
|
||||
|
||||
function->m_wrappedFn.set(vm, globalObject, wrappedFn);
|
||||
|
||||
return function;
|
||||
}
|
||||
|
||||
|
||||
@@ -59,8 +59,9 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
JSWrappingFunction(JSC::VM& vm, JSC::NativeExecutable* native, JSC::JSGlobalObject* globalObject, JSC::Structure* structure)
|
||||
JSWrappingFunction(JSC::VM& vm, JSC::NativeExecutable* native, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, JSC::JSFunction* wrappedFn)
|
||||
: Base(vm, native, globalObject, structure)
|
||||
, m_wrappedFn(wrappedFn, JSC::WriteBarrierEarlyInit)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -152,11 +152,9 @@ JSValue NodeVMModule::evaluate(JSGlobalObject* globalObject, uint32_t timeout, b
|
||||
NodeVMModule::NodeVMModule(JSC::VM& vm, JSC::Structure* structure, WTF::String identifier, JSValue context, JSValue moduleWrapper)
|
||||
: Base(vm, structure)
|
||||
, m_identifier(WTFMove(identifier))
|
||||
, m_context(context && context.isObject() ? asObject(context) : nullptr, JSC::WriteBarrierEarlyInit)
|
||||
, m_moduleWrapper(vm, this, moduleWrapper)
|
||||
{
|
||||
if (context.isObject()) {
|
||||
m_context.set(vm, this, asObject(context));
|
||||
}
|
||||
}
|
||||
|
||||
void NodeVMModule::evaluateDependencies(JSGlobalObject* globalObject, AbstractModuleRecord* record, uint32_t timeout, bool breakOnSigint)
|
||||
|
||||
@@ -105,14 +105,12 @@ NodeVMSourceTextModule* NodeVMSourceTextModule::create(VM& vm, JSGlobalObject* g
|
||||
auto* zigGlobalObject = defaultGlobalObject(globalObject);
|
||||
WTF::String identifier = identifierValue.toWTFString(globalObject);
|
||||
RETURN_IF_EXCEPTION(scope, nullptr);
|
||||
NodeVMSourceTextModule* ptr = new (NotNull, allocateCell<NodeVMSourceTextModule>(vm)) NodeVMSourceTextModule(vm, zigGlobalObject->NodeVMSourceTextModuleStructure(), WTFMove(identifier), contextValue, WTFMove(sourceCode), moduleWrapper);
|
||||
NodeVMSourceTextModule* ptr = new (NotNull, allocateCell<NodeVMSourceTextModule>(vm)) NodeVMSourceTextModule(
|
||||
vm, zigGlobalObject->NodeVMSourceTextModuleStructure(), WTFMove(identifier), contextValue,
|
||||
WTFMove(sourceCode), moduleWrapper, initializeImportMeta);
|
||||
RETURN_IF_EXCEPTION(scope, nullptr);
|
||||
ptr->finishCreation(vm);
|
||||
|
||||
if (!initializeImportMeta.isUndefined()) {
|
||||
ptr->m_initializeImportMeta.set(vm, ptr, initializeImportMeta);
|
||||
}
|
||||
|
||||
if (cachedData.isEmpty()) {
|
||||
return ptr;
|
||||
}
|
||||
@@ -417,7 +415,7 @@ JSUint8Array* NodeVMSourceTextModule::cachedData(JSGlobalObject* globalObject)
|
||||
|
||||
void NodeVMSourceTextModule::initializeImportMeta(JSGlobalObject* globalObject)
|
||||
{
|
||||
if (!m_initializeImportMeta) {
|
||||
if (!m_initializeImportMeta || !m_initializeImportMeta.get().isCallable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -429,8 +427,9 @@ void NodeVMSourceTextModule::initializeImportMeta(JSGlobalObject* globalObject)
|
||||
JSValue metaValue = moduleEnvironment->get(globalObject, globalObject->vm().propertyNames->builtinNames().metaPrivateName());
|
||||
scope.assertNoExceptionExceptTermination();
|
||||
RETURN_IF_EXCEPTION(scope, );
|
||||
ASSERT(metaValue);
|
||||
ASSERT(metaValue.isObject());
|
||||
if (!metaValue || !metaValue.isObject()) {
|
||||
return;
|
||||
}
|
||||
|
||||
CallData callData = JSC::getCallData(m_initializeImportMeta.get());
|
||||
|
||||
|
||||
@@ -57,8 +57,9 @@ private:
|
||||
RefPtr<CachedBytecode> m_bytecode;
|
||||
SourceCode m_sourceCode;
|
||||
|
||||
NodeVMSourceTextModule(JSC::VM& vm, JSC::Structure* structure, WTF::String identifier, JSValue context, SourceCode sourceCode, JSValue moduleWrapper)
|
||||
NodeVMSourceTextModule(JSC::VM& vm, JSC::Structure* structure, WTF::String identifier, JSValue context, SourceCode sourceCode, JSValue moduleWrapper, JSValue initializeImportMeta)
|
||||
: Base(vm, structure, WTFMove(identifier), context, moduleWrapper)
|
||||
, m_initializeImportMeta(initializeImportMeta && !initializeImportMeta.isUndefined() ? initializeImportMeta : JSValue(), JSC::WriteBarrierEarlyInit)
|
||||
, m_sourceCode(WTFMove(sourceCode))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -97,8 +97,8 @@ JSNodeHTTPServerSocket::JSNodeHTTPServerSocket(JSC::VM& vm, JSC::Structure* stru
|
||||
: JSC::JSDestructibleObject(vm, structure)
|
||||
, socket(socket)
|
||||
, is_ssl(is_ssl)
|
||||
, currentResponseObject(response, JSC::WriteBarrierEarlyInit)
|
||||
{
|
||||
currentResponseObject.setEarlyValue(vm, this, response);
|
||||
}
|
||||
|
||||
void JSNodeHTTPServerSocket::detach()
|
||||
|
||||
@@ -12,13 +12,10 @@ using namespace JSC;
|
||||
|
||||
const ClassInfo JSConnectionsList::s_info = { "ConnectionsList"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSConnectionsList) };
|
||||
|
||||
void JSConnectionsList::finishCreation(VM& vm, JSGlobalObject* globalObject, JSSet* allConnections, JSSet* activeConnections)
|
||||
void JSConnectionsList::finishCreation(VM& vm, JSGlobalObject* globalObject)
|
||||
{
|
||||
Base::finishCreation(vm);
|
||||
ASSERT(inherits(info()));
|
||||
|
||||
m_allConnections.set(vm, this, allConnections);
|
||||
m_activeConnections.set(vm, this, activeConnections);
|
||||
}
|
||||
|
||||
template<typename Visitor>
|
||||
|
||||
@@ -20,8 +20,8 @@ public:
|
||||
|
||||
static JSConnectionsList* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, JSC::JSSet* allConnectionsSet, JSC::JSSet* activeConnectionsSet)
|
||||
{
|
||||
JSConnectionsList* instance = new (NotNull, JSC::allocateCell<JSConnectionsList>(vm)) JSConnectionsList(vm, structure);
|
||||
instance->finishCreation(vm, globalObject, allConnectionsSet, activeConnectionsSet);
|
||||
JSConnectionsList* instance = new (NotNull, JSC::allocateCell<JSConnectionsList>(vm)) JSConnectionsList(vm, structure, allConnectionsSet, activeConnectionsSet);
|
||||
instance->finishCreation(vm, globalObject);
|
||||
return instance;
|
||||
}
|
||||
|
||||
@@ -41,10 +41,12 @@ public:
|
||||
DECLARE_INFO;
|
||||
DECLARE_VISIT_CHILDREN;
|
||||
|
||||
void finishCreation(JSC::VM&, JSC::JSGlobalObject*, JSC::JSSet* allConnectionsSet, JSC::JSSet* activeConnectionsSet);
|
||||
void finishCreation(JSC::VM&, JSC::JSGlobalObject*);
|
||||
|
||||
JSConnectionsList(JSC::VM& vm, JSC::Structure* structure)
|
||||
JSConnectionsList(JSC::VM& vm, JSC::Structure* structure, JSC::JSSet* allConnections, JSC::JSSet* activeConnections)
|
||||
: Base(vm, structure)
|
||||
, m_allConnections(allConnections, JSC::WriteBarrierEarlyInit)
|
||||
, m_activeConnections(activeConnections, JSC::WriteBarrierEarlyInit)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user