mirror of
https://github.com/oven-sh/bun
synced 2026-02-12 20:09:04 +00:00
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
¤tScriptExecutionOwner,
|
||||
&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,
|
||||
¤tScriptExecutionOwner,
|
||||
&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,
|
||||
¤tScriptExecutionOwner,
|
||||
&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,
|
||||
¤tScriptExecutionOwner,
|
||||
&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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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)))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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.]+)?$/);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user