Revert "Remove most static initializers (#19298)" (#19353)

This commit is contained in:
190n
2025-04-28 15:54:31 -07:00
committed by GitHub
parent ec6cb8283e
commit 7b134693d6
14 changed files with 183 additions and 369 deletions

View File

@@ -1014,10 +1014,6 @@ if(LINUX)
-Wl,--compress-debug-sections=zlib
-Wl,-z,lazy
-Wl,-z,norelro
# enable string tail merging
-Wl,-O2
# make debug info faster to load
-Wl,--gdb-index
-Wl,-z,combreloc
-Wl,--no-eh-frame-hdr
-Wl,--sort-section=name

View File

@@ -128,6 +128,34 @@ JSC::JSInternalPromise* bakeModuleLoaderFetch(JSC::JSGlobalObject* globalObject,
return Zig::GlobalObject::moduleLoaderFetch(globalObject, loader, key, parameters, script);
}
#define INHERIT_HOOK_METHOD(name) \
Zig::GlobalObject::s_globalObjectMethodTable.name
const JSC::GlobalObjectMethodTable GlobalObject::s_globalObjectMethodTable = {
INHERIT_HOOK_METHOD(supportsRichSourceInfo),
INHERIT_HOOK_METHOD(shouldInterruptScript),
INHERIT_HOOK_METHOD(javaScriptRuntimeFlags),
INHERIT_HOOK_METHOD(queueMicrotaskToEventLoop),
INHERIT_HOOK_METHOD(shouldInterruptScriptBeforeTimeout),
bakeModuleLoaderImportModule,
bakeModuleLoaderResolve,
bakeModuleLoaderFetch,
INHERIT_HOOK_METHOD(moduleLoaderCreateImportMetaProperties),
INHERIT_HOOK_METHOD(moduleLoaderEvaluate),
INHERIT_HOOK_METHOD(promiseRejectionTracker),
INHERIT_HOOK_METHOD(reportUncaughtExceptionAtEventLoop),
INHERIT_HOOK_METHOD(currentScriptExecutionOwner),
INHERIT_HOOK_METHOD(scriptExecutionStatus),
INHERIT_HOOK_METHOD(reportViolationForUnsafeEval),
INHERIT_HOOK_METHOD(defaultLanguage),
INHERIT_HOOK_METHOD(compileStreaming),
INHERIT_HOOK_METHOD(instantiateStreaming),
INHERIT_HOOK_METHOD(deriveShadowRealmGlobalObject),
INHERIT_HOOK_METHOD(codeForEval),
INHERIT_HOOK_METHOD(canCompileStrings),
INHERIT_HOOK_METHOD(trustedScriptStructure),
};
GlobalObject* GlobalObject::create(JSC::VM& vm, JSC::Structure* structure,
const JSC::GlobalObjectMethodTable* methodTable)
{
@@ -153,40 +181,6 @@ JSC::Structure* GlobalObject::createStructure(JSC::VM& vm)
struct BunVirtualMachine;
extern "C" BunVirtualMachine* Bun__getVM();
const JSC::GlobalObjectMethodTable& GlobalObject::globalObjectMethodTable()
{
const auto& parent = Zig::GlobalObject::globalObjectMethodTable();
#define INHERIT_HOOK_METHOD(name) \
parent.name
static const JSC::GlobalObjectMethodTable table = {
INHERIT_HOOK_METHOD(supportsRichSourceInfo),
INHERIT_HOOK_METHOD(shouldInterruptScript),
INHERIT_HOOK_METHOD(javaScriptRuntimeFlags),
INHERIT_HOOK_METHOD(queueMicrotaskToEventLoop),
INHERIT_HOOK_METHOD(shouldInterruptScriptBeforeTimeout),
bakeModuleLoaderImportModule,
bakeModuleLoaderResolve,
bakeModuleLoaderFetch,
INHERIT_HOOK_METHOD(moduleLoaderCreateImportMetaProperties),
INHERIT_HOOK_METHOD(moduleLoaderEvaluate),
INHERIT_HOOK_METHOD(promiseRejectionTracker),
INHERIT_HOOK_METHOD(reportUncaughtExceptionAtEventLoop),
INHERIT_HOOK_METHOD(currentScriptExecutionOwner),
INHERIT_HOOK_METHOD(scriptExecutionStatus),
INHERIT_HOOK_METHOD(reportViolationForUnsafeEval),
INHERIT_HOOK_METHOD(defaultLanguage),
INHERIT_HOOK_METHOD(compileStreaming),
INHERIT_HOOK_METHOD(instantiateStreaming),
INHERIT_HOOK_METHOD(deriveShadowRealmGlobalObject),
INHERIT_HOOK_METHOD(codeForEval),
INHERIT_HOOK_METHOD(canCompileStrings),
INHERIT_HOOK_METHOD(trustedScriptStructure),
};
#undef INHERIT_HOOK_METHOD
return table;
}
// A lot of this function is taken from 'Zig__GlobalObject__create'
// TODO: remove this entire method
extern "C" GlobalObject* BakeCreateProdGlobal(void* console)
@@ -199,7 +193,7 @@ extern "C" GlobalObject* BakeCreateProdGlobal(void* console)
JSC::Structure* structure = Bake::GlobalObject::createStructure(vm);
Bake::GlobalObject* global = Bake::GlobalObject::create(
vm, structure, &Bake::GlobalObject::globalObjectMethodTable());
vm, structure, &Bake::GlobalObject::s_globalObjectMethodTable);
if (!global)
BUN_PANIC("Failed to create BakeGlobalObject");

View File

@@ -26,7 +26,7 @@ public:
[](auto& server) -> JSC::HeapCellType& { return server.m_heapCellTypeForBakeGlobalObject; });
}
static const JSC::GlobalObjectMethodTable& globalObjectMethodTable();
static const JSC::GlobalObjectMethodTable s_globalObjectMethodTable;
static GlobalObject* create(JSC::VM& vm, JSC::Structure* structure, const JSC::GlobalObjectMethodTable* methodTable);
static JSC::Structure* createStructure(JSC::VM& vm);

View File

@@ -89,33 +89,36 @@ using namespace WebCore;
JSC_DECLARE_HOST_FUNCTION(constructJSBuffer);
JSC_DECLARE_HOST_FUNCTION(callJSBuffer);
JSC_DECLARE_HOST_FUNCTION(jsBufferConstructorFunction_alloc);
JSC_DECLARE_HOST_FUNCTION(jsBufferConstructorFunction_allocUnsafe);
JSC_DECLARE_HOST_FUNCTION(jsBufferConstructorFunction_allocUnsafeSlow);
JSC_DECLARE_HOST_FUNCTION(jsBufferConstructorFunction_byteLength);
JSC_DECLARE_HOST_FUNCTION(jsBufferConstructorFunction_compare);
JSC_DECLARE_HOST_FUNCTION(jsBufferConstructorFunction_concat);
JSC_DECLARE_HOST_FUNCTION(jsBufferConstructorFunction_copyBytesFrom);
JSC_DECLARE_HOST_FUNCTION(jsBufferConstructorFunction_isBuffer);
JSC_DECLARE_HOST_FUNCTION(jsBufferConstructorFunction_isEncoding);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-function"
static JSC_DECLARE_HOST_FUNCTION(jsBufferConstructorFunction_alloc);
static JSC_DECLARE_HOST_FUNCTION(jsBufferConstructorFunction_allocUnsafe);
static JSC_DECLARE_HOST_FUNCTION(jsBufferConstructorFunction_allocUnsafeSlow);
static JSC_DECLARE_HOST_FUNCTION(jsBufferConstructorFunction_byteLength);
static JSC_DECLARE_HOST_FUNCTION(jsBufferConstructorFunction_compare);
static JSC_DECLARE_HOST_FUNCTION(jsBufferConstructorFunction_concat);
static JSC_DECLARE_HOST_FUNCTION(jsBufferConstructorFunction_copyBytesFrom);
static JSC_DECLARE_HOST_FUNCTION(jsBufferConstructorFunction_isBuffer);
static JSC_DECLARE_HOST_FUNCTION(jsBufferConstructorFunction_isEncoding);
JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_compare);
JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_copy);
JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_equals);
JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_fill);
JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_includes);
JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_indexOf);
JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_inspect);
JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_lastIndexOf);
JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_swap16);
JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_swap32);
JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_swap64);
JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_toString);
JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_write);
JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_writeBigInt64LE);
JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_writeBigInt64BE);
JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_writeBigUInt64LE);
JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_writeBigUInt64BE);
static JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_compare);
static JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_copy);
static JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_equals);
static JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_fill);
static JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_includes);
static JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_indexOf);
static JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_inspect);
static JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_lastIndexOf);
static JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_swap16);
static JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_swap32);
static JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_swap64);
static JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_toString);
static JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_write);
static JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_writeBigInt64LE);
static JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_writeBigInt64BE);
static JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_writeBigUInt64LE);
static JSC_DECLARE_HOST_FUNCTION(jsBufferPrototypeFunction_writeBigUInt64BE);
#pragma clang diagnostic pop
extern "C" EncodedJSValue WebCore_BufferEncodingType_toJS(JSC::JSGlobalObject* lexicalGlobalObject, WebCore::BufferEncodingType encoding)
{
@@ -2263,7 +2266,7 @@ class JSBuffer : public JSC::JSNonFinalObject {
const ClassInfo JSBuffer::s_info = {
"Buffer"_s,
&JSC::JSUint8Array::s_info,
JSC::getUint8ArrayClassInfo(),
nullptr,
nullptr,
CREATE_METHOD_TABLE(JSBuffer)

View File

@@ -847,14 +847,14 @@ static void cleanupAsyncHooksData(JSC::VM& vm)
GlobalObject* GlobalObject::create(JSC::VM& vm, JSC::Structure* structure)
{
GlobalObject* ptr = new (NotNull, JSC::allocateCell<GlobalObject>(vm)) GlobalObject(vm, structure, &globalObjectMethodTable());
GlobalObject* ptr = new (NotNull, JSC::allocateCell<GlobalObject>(vm)) GlobalObject(vm, structure, &s_globalObjectMethodTable);
ptr->finishCreation(vm);
return ptr;
}
GlobalObject* GlobalObject::create(JSC::VM& vm, JSC::Structure* structure, uint32_t scriptExecutionContextId)
{
GlobalObject* ptr = new (NotNull, JSC::allocateCell<GlobalObject>(vm)) GlobalObject(vm, structure, scriptExecutionContextId, &globalObjectMethodTable());
GlobalObject* ptr = new (NotNull, JSC::allocateCell<GlobalObject>(vm)) GlobalObject(vm, structure, scriptExecutionContextId, &s_globalObjectMethodTable);
ptr->finishCreation(vm);
return ptr;
}
@@ -954,7 +954,7 @@ extern "C" JSC::JSGlobalObject* Zig__GlobalObject__create(void* console_client,
return Zig::EvalGlobalObject::create(
vm,
structure,
&Zig::EvalGlobalObject::globalObjectMethodTable());
&Zig::EvalGlobalObject::s_globalObjectMethodTable);
} else {
auto* structure = Zig::GlobalObject::createStructure(vm);
@@ -1189,64 +1189,57 @@ JSC::ScriptExecutionStatus Zig::GlobalObject::scriptExecutionStatus(JSC::JSGloba
}
}
}
const JSC::GlobalObjectMethodTable& GlobalObject::globalObjectMethodTable()
{
static const JSC::GlobalObjectMethodTable table = {
&supportsRichSourceInfo,
&shouldInterruptScript,
&javaScriptRuntimeFlags,
nullptr, // &queueMicrotaskToEventLoop, // queueTaskToEventLoop
nullptr, // &shouldInterruptScriptBeforeTimeout,
&moduleLoaderImportModule, // moduleLoaderImportModule
&moduleLoaderResolve, // moduleLoaderResolve
&moduleLoaderFetch, // moduleLoaderFetch
&moduleLoaderCreateImportMetaProperties, // moduleLoaderCreateImportMetaProperties
&moduleLoaderEvaluate, // moduleLoaderEvaluate
&promiseRejectionTracker, // promiseRejectionTracker
&reportUncaughtExceptionAtEventLoop,
&currentScriptExecutionOwner,
&scriptExecutionStatus,
nullptr, // reportViolationForUnsafeEval
nullptr, // defaultLanguage
nullptr, // compileStreaming
nullptr, // instantiateStreaming
&Zig::deriveShadowRealmGlobalObject,
&codeForEval, // codeForEval
&canCompileStrings, // canCompileStrings
&trustedScriptStructure, // trustedScriptStructure
};
return table;
}
const JSC::GlobalObjectMethodTable& EvalGlobalObject::globalObjectMethodTable()
{
static const JSC::GlobalObjectMethodTable table = {
&supportsRichSourceInfo,
&shouldInterruptScript,
&javaScriptRuntimeFlags,
// &queueMicrotaskToEventLoop, // queueTaskToEventLoop
nullptr,
nullptr, // &shouldInterruptScriptBeforeTimeout,
&moduleLoaderImportModule, // moduleLoaderImportModule
&moduleLoaderResolve, // moduleLoaderResolve
&moduleLoaderFetch, // moduleLoaderFetch
&moduleLoaderCreateImportMetaProperties, // moduleLoaderCreateImportMetaProperties
&moduleLoaderEvaluate, // moduleLoaderEvaluate
&promiseRejectionTracker, // promiseRejectionTracker
&reportUncaughtExceptionAtEventLoop,
&currentScriptExecutionOwner,
&scriptExecutionStatus,
nullptr, // reportViolationForUnsafeEval
nullptr, // defaultLanguage
nullptr, // compileStreaming
nullptr, // instantiateStreaming
&Zig::deriveShadowRealmGlobalObject,
&codeForEval, // codeForEval
&canCompileStrings, // canCompileStrings
&trustedScriptStructure, // trustedScriptStructure
};
return table;
}
const JSC::GlobalObjectMethodTable GlobalObject::s_globalObjectMethodTable = {
&supportsRichSourceInfo,
&shouldInterruptScript,
&javaScriptRuntimeFlags,
nullptr, // &queueMicrotaskToEventLoop, // queueTaskToEventLoop
nullptr, // &shouldInterruptScriptBeforeTimeout,
&moduleLoaderImportModule, // moduleLoaderImportModule
&moduleLoaderResolve, // moduleLoaderResolve
&moduleLoaderFetch, // moduleLoaderFetch
&moduleLoaderCreateImportMetaProperties, // moduleLoaderCreateImportMetaProperties
&moduleLoaderEvaluate, // moduleLoaderEvaluate
&promiseRejectionTracker, // promiseRejectionTracker
&reportUncaughtExceptionAtEventLoop,
&currentScriptExecutionOwner,
&scriptExecutionStatus,
nullptr, // reportViolationForUnsafeEval
nullptr, // defaultLanguage
nullptr, // compileStreaming
nullptr, // instantiateStreaming
&Zig::deriveShadowRealmGlobalObject,
&codeForEval, // codeForEval
&canCompileStrings, // canCompileStrings
&trustedScriptStructure, // trustedScriptStructure
};
const JSC::GlobalObjectMethodTable EvalGlobalObject::s_globalObjectMethodTable = {
&supportsRichSourceInfo,
&shouldInterruptScript,
&javaScriptRuntimeFlags,
// &queueMicrotaskToEventLoop, // queueTaskToEventLoop
nullptr,
nullptr, // &shouldInterruptScriptBeforeTimeout,
&moduleLoaderImportModule, // moduleLoaderImportModule
&moduleLoaderResolve, // moduleLoaderResolve
&moduleLoaderFetch, // moduleLoaderFetch
&moduleLoaderCreateImportMetaProperties, // moduleLoaderCreateImportMetaProperties
&moduleLoaderEvaluate, // moduleLoaderEvaluate
&promiseRejectionTracker, // promiseRejectionTracker
&reportUncaughtExceptionAtEventLoop,
&currentScriptExecutionOwner,
&scriptExecutionStatus,
nullptr, // reportViolationForUnsafeEval
nullptr, // defaultLanguage
nullptr, // compileStreaming
nullptr, // instantiateStreaming
&Zig::deriveShadowRealmGlobalObject,
&codeForEval, // codeForEval
&canCompileStrings, // canCompileStrings
&trustedScriptStructure, // trustedScriptStructure
};
GlobalObject::GlobalObject(JSC::VM& vm, JSC::Structure* structure, const JSC::GlobalObjectMethodTable* methodTable)
: Base(vm, structure, methodTable)

View File

@@ -102,10 +102,9 @@ public:
}
static const JSC::ClassInfo s_info;
static const JSC::GlobalObjectMethodTable& globalObjectMethodTable();
static const JSC::GlobalObjectMethodTable s_globalObjectMethodTable;
template<typename, JSC::SubspaceAccess mode>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
if constexpr (mode == JSC::SubspaceAccess::Concurrently)
return nullptr;
@@ -701,11 +700,11 @@ private:
class EvalGlobalObject : public GlobalObject {
public:
static const JSC::GlobalObjectMethodTable& globalObjectMethodTable();
static const JSC::GlobalObjectMethodTable s_globalObjectMethodTable;
static JSC::JSValue moduleLoaderEvaluate(JSGlobalObject*, JSC::JSModuleLoader*, JSC::JSValue, JSC::JSValue, JSC::JSValue, JSC::JSValue, JSC::JSValue);
EvalGlobalObject(JSC::VM& vm, JSC::Structure* structure)
: GlobalObject(vm, structure, &globalObjectMethodTable())
: GlobalObject(vm, structure, &s_globalObjectMethodTable)
{
}
};

View File

@@ -1341,25 +1341,18 @@ std::optional<WTF::String> X509View::getFingerprint(
{
unsigned int md_size;
unsigned char md[EVP_MAX_MD_SIZE];
static const char hex[] = "0123456789ABCDEF";
static constexpr char hex[] = "0123456789ABCDEF";
if (X509_digest(get(), method, md, &md_size)) {
if (md_size == 0) return std::nullopt;
std::span<LChar> fingerprint;
WTF::String fingerprintStr = WTF::String::createUninitialized((md_size * 3) - 1, fingerprint);
{
// This function is 650 KB.
// It should not be 650 KB.
unsigned int i = 0;
unsigned int idx = 0;
do {
const unsigned int md_i = md[i++];
fingerprint[idx++] = hex[(md_i & 0xf0) >> 4];
fingerprint[idx++] = hex[(md_i & 0x0f)];
if (i == md_size) break;
fingerprint[idx++] = ':';
} while (i < md_size);
for (unsigned int i = 0; i < md_size; i++) {
auto idx = 3 * i;
fingerprint[idx] = hex[(md[i] & 0xf0) >> 4];
fingerprint[idx + 1] = hex[(md[i] & 0x0f)];
if (i == md_size - 1) break;
fingerprint[idx + 2] = ':';
}
return fingerprintStr;
@@ -3136,9 +3129,9 @@ const Cipher Cipher::FromName(WTF::StringView name)
if (name.startsWithIgnoringASCIICase("aes"_s)) {
auto remain = name.substring(3);
if (remain == "128"_s) return Cipher::AES_128_CBC();
if (remain == "192"_s) return Cipher::AES_192_CBC();
if (remain == "256"_s) return Cipher::AES_256_CBC();
if (remain == "128"_s) return Cipher::AES_128_CBC;
if (remain == "192"_s) return Cipher::AES_192_CBC;
if (remain == "256"_s) return Cipher::AES_256_CBC;
}
auto nameUtf8 = name.utf8();
@@ -3155,71 +3148,19 @@ const Cipher Cipher::FromCtx(const CipherCtxPointer& ctx)
return Cipher(EVP_CIPHER_CTX_cipher(ctx.get()));
}
const Cipher& Cipher::EMPTY()
{
static const Cipher cipher = Cipher();
return cipher;
}
const Cipher& Cipher::AES_128_CBC()
{
static const Cipher cipher = Cipher::FromNid(NID_aes_128_cbc);
return cipher;
}
const Cipher& Cipher::AES_192_CBC()
{
static const Cipher cipher = Cipher::FromNid(NID_aes_192_cbc);
return cipher;
}
const Cipher& Cipher::AES_256_CBC()
{
static const Cipher cipher = Cipher::FromNid(NID_aes_256_cbc);
return cipher;
}
const Cipher& Cipher::AES_128_CTR()
{
static const Cipher cipher = Cipher::FromNid(NID_aes_128_ctr);
return cipher;
}
const Cipher& Cipher::AES_192_CTR()
{
static const Cipher cipher = Cipher::FromNid(NID_aes_192_ctr);
return cipher;
}
const Cipher& Cipher::AES_256_CTR()
{
static const Cipher cipher = Cipher::FromNid(NID_aes_256_ctr);
return cipher;
}
const Cipher& Cipher::AES_128_GCM()
{
static const Cipher cipher = Cipher::FromNid(NID_aes_128_gcm);
return cipher;
}
const Cipher& Cipher::AES_192_GCM()
{
static const Cipher cipher = Cipher::FromNid(NID_aes_192_gcm);
return cipher;
}
const Cipher& Cipher::AES_256_GCM()
{
static const Cipher cipher = Cipher::FromNid(NID_aes_256_gcm);
return cipher;
}
const Cipher& Cipher::AES_128_KW()
{
static const Cipher cipher = Cipher::FromNid(NID_id_aes128_wrap);
return cipher;
}
const Cipher& Cipher::AES_192_KW()
{
static const Cipher cipher = Cipher::FromNid(NID_id_aes192_wrap);
return cipher;
}
const Cipher& Cipher::AES_256_KW()
{
static const Cipher cipher = Cipher::FromNid(NID_id_aes256_wrap);
return cipher;
}
const Cipher Cipher::EMPTY = Cipher();
const Cipher Cipher::AES_128_CBC = Cipher::FromNid(NID_aes_128_cbc);
const Cipher Cipher::AES_192_CBC = Cipher::FromNid(NID_aes_192_cbc);
const Cipher Cipher::AES_256_CBC = Cipher::FromNid(NID_aes_256_cbc);
const Cipher Cipher::AES_128_CTR = Cipher::FromNid(NID_aes_128_ctr);
const Cipher Cipher::AES_192_CTR = Cipher::FromNid(NID_aes_192_ctr);
const Cipher Cipher::AES_256_CTR = Cipher::FromNid(NID_aes_256_ctr);
const Cipher Cipher::AES_128_GCM = Cipher::FromNid(NID_aes_128_gcm);
const Cipher Cipher::AES_192_GCM = Cipher::FromNid(NID_aes_192_gcm);
const Cipher Cipher::AES_256_GCM = Cipher::FromNid(NID_aes_256_gcm);
const Cipher Cipher::AES_128_KW = Cipher::FromNid(NID_id_aes128_wrap);
const Cipher Cipher::AES_192_KW = Cipher::FromNid(NID_id_aes192_wrap);
const Cipher Cipher::AES_256_KW = Cipher::FromNid(NID_id_aes256_wrap);
bool Cipher::isGcmMode() const
{
@@ -3353,7 +3294,7 @@ int Cipher::bytesToKey(const Digest& digest,
unsigned char* iv) const
{
return EVP_BytesToKey(
*this, Digest::MD5(), nullptr, input.data, input.len, 1, key, iv);
*this, Digest::MD5, nullptr, input.data, input.len, 1, key, iv);
}
// ============================================================================
@@ -4919,31 +4860,12 @@ size_t Digest::size() const
return EVP_MD_size(md_);
}
const Digest& Digest::MD5()
{
static const Digest digest = Digest(EVP_md5());
return digest;
}
const Digest& Digest::SHA1()
{
static const Digest digest = Digest(EVP_sha1());
return digest;
}
const Digest& Digest::SHA256()
{
static const Digest digest = Digest(EVP_sha256());
return digest;
}
const Digest& Digest::SHA384()
{
static const Digest digest = Digest(EVP_sha384());
return digest;
}
const Digest& Digest::SHA512()
{
static const Digest digest = Digest(EVP_sha512());
return digest;
}
const Digest Digest::MD5 = Digest(EVP_md5());
const Digest Digest::SHA1 = Digest(EVP_sha1());
const Digest Digest::SHA256 = Digest(EVP_sha256());
const Digest Digest::SHA384 = Digest(EVP_sha384());
const Digest Digest::SHA512 = Digest(EVP_sha512());
const Digest Digest::FromName(WTF::StringView name)
{
return ncrypto::getDigestByName(name);

View File

@@ -273,11 +273,11 @@ public:
inline operator const EVP_MD*() const { return md_; }
inline operator bool() const { return md_ != nullptr; }
static const Digest& MD5();
static const Digest& SHA1();
static const Digest& SHA256();
static const Digest& SHA384();
static const Digest& SHA512();
static const Digest MD5;
static const Digest SHA1;
static const Digest SHA256;
static const Digest SHA384;
static const Digest SHA512;
static const Digest FromName(WTF::StringView name);
@@ -349,19 +349,19 @@ public:
// the result will be an empty Cipher object whose bool operator
// will return false.
static const Cipher& EMPTY();
static const Cipher& AES_128_CBC();
static const Cipher& AES_192_CBC();
static const Cipher& AES_256_CBC();
static const Cipher& AES_128_CTR();
static const Cipher& AES_192_CTR();
static const Cipher& AES_256_CTR();
static const Cipher& AES_128_GCM();
static const Cipher& AES_192_GCM();
static const Cipher& AES_256_GCM();
static const Cipher& AES_128_KW();
static const Cipher& AES_192_KW();
static const Cipher& AES_256_KW();
static const Cipher EMPTY;
static const Cipher AES_128_CBC;
static const Cipher AES_192_CBC;
static const Cipher AES_256_CBC;
static const Cipher AES_128_CTR;
static const Cipher AES_192_CTR;
static const Cipher AES_256_CTR;
static const Cipher AES_128_GCM;
static const Cipher AES_192_GCM;
static const Cipher AES_256_GCM;
static const Cipher AES_128_KW;
static const Cipher AES_192_KW;
static const Cipher AES_256_KW;
struct CipherParams {
int padding;

View File

@@ -20,9 +20,9 @@ public:
{
// TODO(@190n) handle more types
if (value.isString()) {
return Local<T>(m_buffer->createHandle(value.asCell(), &shim::Map::string_map(), vm));
return Local<T>(m_buffer->createHandle(value.asCell(), &shim::Map::string_map, vm));
} else if (value.isCell()) {
return Local<T>(m_buffer->createHandle(value.asCell(), &shim::Map::object_map(), vm));
return Local<T>(m_buffer->createHandle(value.asCell(), &shim::Map::object_map, vm));
} else if (value.isInt32()) {
return Local<T>(m_buffer->createSmiHandle(value.asInt32()));
} else if (value.isNumber()) {

View File

@@ -29,7 +29,7 @@ struct ObjectLayout {
}
ObjectLayout(double number)
: m_taggedMap(const_cast<Map*>(&Map::heap_number_map()))
: m_taggedMap(const_cast<Map*>(&Map::heap_number_map))
, m_contents({ .number = number })
{
}
@@ -80,10 +80,10 @@ struct Handle {
}
const Map* map_ptr = m_object.map();
// TODO(@190n) exhaustively switch on InstanceType
if (map_ptr == &Map::object_map() || map_ptr == &Map::string_map()) {
if (map_ptr == &Map::object_map || map_ptr == &Map::string_map) {
return true;
} else if (map_ptr == &Map::map_map() || map_ptr == &Map::oddball_map()
|| map_ptr == &Map::heap_number_map()) {
} else if (map_ptr == &Map::map_map || map_ptr == &Map::oddball_map
|| map_ptr == &Map::heap_number_map) {
return false;
} else {
RELEASE_ASSERT_NOT_REACHED("unknown Map at %p with instance type %" PRIx16,

View File

@@ -23,33 +23,11 @@ namespace v8 {
namespace shim {
// TODO give these more appropriate instance types
// Prevent static initialization on startup
const Map& Map::map_map()
{
static const Map map = Map(MapMapTag::MapMap);
return map;
}
const Map& Map::object_map()
{
static const Map map = Map(InstanceType::Object);
return map;
}
const Map& Map::oddball_map()
{
static const Map map = Map(InstanceType::Oddball);
return map;
}
const Map& Map::string_map()
{
static const Map map = Map(InstanceType::String);
return map;
}
const Map& Map::heap_number_map()
{
static const Map map = Map(InstanceType::HeapNumber);
return map;
}
const Map Map::map_map(InstanceType::Object);
const Map Map::object_map(InstanceType::Object);
const Map Map::oddball_map(InstanceType::Oddball);
const Map Map::string_map(InstanceType::String);
const Map Map::heap_number_map(InstanceType::HeapNumber);
} // namespace shim
} // namespace v8

View File

@@ -34,38 +34,25 @@ struct Map {
InstanceType m_instanceType;
// Since maps are V8 objects, they each also have a map pointer at the start, which is this one
static const Map& map_map();
static const Map map_map;
// All V8 values not covered by a more specific map use this one
static const Map& object_map();
static const Map object_map;
// The map used by null, undefined, true, and false. Required since V8 checks these values'
// instance type in the inline QuickIs* functions
static const Map& oddball_map();
static const Map oddball_map;
// All strings use this map. Required since V8's inline QuickIsString() checks the instance
// type.
static const Map& string_map();
static const Map string_map;
// Handles containing a double instead of a JSCell pointer use this map so that we can tell they
// are numbers.
static const Map& heap_number_map();
static const Map heap_number_map;
Map(InstanceType instance_type)
: m_metaMap(const_cast<Map*>(&map_map()))
: m_metaMap(const_cast<Map*>(&map_map))
, m_unused(0xaaaaaaaa)
, m_instanceType(instance_type)
{
}
// Tag it as the map_map() Map
enum class MapMapTag {
MapMap
};
public:
Map(MapMapTag)
: m_metaMap(const_cast<Map*>(this))
, m_unused(0xaaaaaaaa)
, m_instanceType(InstanceType::Object)
{
}
};
static_assert(sizeof(Map) == 16, "Map has wrong layout");

View File

@@ -21,7 +21,7 @@ struct Oddball {
TaggedPointer m_kind;
Oddball(Kind kind)
: m_map(const_cast<Map*>(&Map::oddball_map()))
: m_map(const_cast<Map*>(&Map::oddball_map))
, m_kind(TaggedPointer(static_cast<int>(kind)))
{
}

View File

@@ -1,58 +0,0 @@
import { describe, expect, it } from "bun:test";
import { bunEnv, bunExe, isMacOS } from "harness";
/**
* This test prevents startup performance regressions by ensuring that Bun has
* exactly one static initializer from its own executable.
*
* Static initializers are functions that run automatically when a program starts, before main() is called.
* They're used to initialize global variables and static class members, but come with performance costs:
*
* 1. They always execute at startup, even if the initialized values are never used
* 2. They can't be optimized away by the compiler
* 3. They add to the binary size
* 4. They increase startup time
* 5. They can introduce complex initialization order dependencies
*
* On macOS, we can use DYLD_PRINT_INITIALIZERS to detect static initializers.
* This test verifies that Bun has exactly one static initializer from its own executable.
*
* Adding more static initializers would degrade Bun's startup performance.
*/
describe("static initializers", () => {
// Only macOS has DYLD_PRINT_INITIALIZERS
it.skipIf(!isMacOS || process.arch !== "arm64")("should only have one static initializer from bun itself", () => {
const env = {
...bunEnv,
DYLD_PRINT_INITIALIZERS: "1",
} as const;
const result = Bun.spawnSync({
cmd: [bunExe(), "--version"],
env,
});
expect(result.exitCode).toBe(0);
const stdout = result.stdout.toString();
const stderr = result.stderr.toString();
// Combine stdout and stderr since DYLD_PRINT_INITIALIZERS output goes to stderr
const output = stderr + stdout;
// Get all lines that contain initializers from the bun executable
const bunInitializers = output
.split("\n")
.map(a => a.trim())
.filter(line => line.includes("running initializer") && line.includes(bunExe()));
// We expect exactly one initializer from the bun executable itself
expect(
bunInitializers.length,
`Do not add static initializers to Bun. Static initializers are called when Bun starts up, regardless of whether you use the variables or not. This makes Bun slower.`,
).toBe(1);
// Verify the version was printed correctly
expect(stdout.trim()).toMatch(/^\d+\.\d+\.\d+(-[a-z0-9.]+)?$/);
});
});