mirror of
https://github.com/oven-sh/bun
synced 2026-02-10 02:48:50 +00:00
fix: adapt Bun bindings to WebKit upstream changes
- Update QueuedTask constructor calls to use new payload parameter - BunPerformMicrotaskJob now handles async context directly (saves one argument slot) - Replace SortedArrayMap usage with if-else chains (API changed in WTF) - Fix typos: DOMEGCOutputConstraint -> DOMGCOutputConstraint - Fix WTF_MAKE_TZONE_ALLOCATED macro argument in CryptoSignJob.h - Update code generators (bindgen.ts, enumeration.ts) to not use SortedArrayMap Claude-Generated-By: Claude Code (cli/claude-opus-4-5=100%) Claude-Steers: 13
This commit is contained in:
@@ -36,7 +36,7 @@ namespace WebCore {
|
||||
class JSHeapData;
|
||||
|
||||
class DOMGCOutputConstraint : public JSC::MarkingConstraint {
|
||||
WTF_DEPRECATED_MAKE_FAST_ALLOCATED(DOMEGCOutputConstraint);
|
||||
WTF_DEPRECATED_MAKE_FAST_ALLOCATED(DOMGCOutputConstraint);
|
||||
|
||||
public:
|
||||
DOMGCOutputConstraint(JSC::VM&, JSHeapData&);
|
||||
|
||||
@@ -1059,9 +1059,7 @@ JSC_DEFINE_HOST_FUNCTION(functionQueueMicrotask,
|
||||
|
||||
auto* globalObject = defaultGlobalObject(lexicalGlobalObject);
|
||||
JSC::JSValue asyncContext = globalObject->m_asyncContextData.get()->getInternalField(0);
|
||||
auto function = globalObject->performMicrotaskFunction();
|
||||
#if ASSERT_ENABLED
|
||||
ASSERT_WITH_MESSAGE(function, "Invalid microtask function");
|
||||
ASSERT_WITH_MESSAGE(!callback.isEmpty(), "Invalid microtask callback");
|
||||
#endif
|
||||
|
||||
@@ -1069,10 +1067,9 @@ JSC_DEFINE_HOST_FUNCTION(functionQueueMicrotask,
|
||||
asyncContext = JSC::jsUndefined();
|
||||
}
|
||||
|
||||
// BunPerformMicrotaskJob accepts a variable number of arguments (up to: performMicrotask, job, asyncContext, arg0, arg1).
|
||||
// The runtime inspects argumentCount to determine which arguments are present, so callers may pass only the subset they need.
|
||||
// Here we pass: function, callback, asyncContext.
|
||||
JSC::QueuedTask task { nullptr, JSC::InternalMicrotask::BunPerformMicrotaskJob, globalObject, function, callback, asyncContext };
|
||||
// BunPerformMicrotaskJob now handles async context directly:
|
||||
// arguments[0]: job function, arguments[1]: asyncContext
|
||||
JSC::QueuedTask task { nullptr, JSC::InternalMicrotask::BunPerformMicrotaskJob, 0, globalObject, callback, asyncContext };
|
||||
globalObject->vm().queueMicrotask(WTF::move(task));
|
||||
|
||||
return JSC::JSValue::encode(JSC::jsUndefined());
|
||||
@@ -3103,7 +3100,7 @@ extern "C" void JSC__JSGlobalObject__queueMicrotaskCallback(Zig::GlobalObject* g
|
||||
|
||||
// Do not use JSCell* here because the GC will try to visit it.
|
||||
// Use BunInvokeJobWithArguments to pass the two arguments (ptr and callback) to the trampoline function
|
||||
JSC::QueuedTask task { nullptr, JSC::InternalMicrotask::BunInvokeJobWithArguments, globalObject, function, JSValue(std::bit_cast<double>(reinterpret_cast<uintptr_t>(ptr))), JSValue(std::bit_cast<double>(reinterpret_cast<uintptr_t>(callback))) };
|
||||
JSC::QueuedTask task { nullptr, JSC::InternalMicrotask::BunInvokeJobWithArguments, 0, globalObject, function, JSValue(std::bit_cast<double>(reinterpret_cast<uintptr_t>(ptr))), JSValue(std::bit_cast<double>(reinterpret_cast<uintptr_t>(callback))) };
|
||||
globalObject->vm().queueMicrotask(WTF::move(task));
|
||||
}
|
||||
|
||||
|
||||
@@ -3521,13 +3521,11 @@ void JSC__JSPromise__rejectOnNextTickWithHandled(JSC::JSPromise* promise, JSC::J
|
||||
|
||||
promise->internalField(JSC::JSPromise::Field::Flags).set(vm, promise, jsNumber(flags | JSC::JSPromise::isFirstResolvingFunctionCalledFlag));
|
||||
auto* globalObject = jsCast<Zig::GlobalObject*>(promise->globalObject());
|
||||
auto microtaskFunction = globalObject->performMicrotaskFunction();
|
||||
auto rejectPromiseFunction = globalObject->rejectPromiseFunction();
|
||||
|
||||
auto asyncContext = globalObject->m_asyncContextData.get()->getInternalField(0);
|
||||
|
||||
#if ASSERT_ENABLED
|
||||
ASSERT_WITH_MESSAGE(microtaskFunction, "Invalid microtask function");
|
||||
ASSERT_WITH_MESSAGE(rejectPromiseFunction, "Invalid microtask callback");
|
||||
ASSERT_WITH_MESSAGE(!value.isEmpty(), "Invalid microtask value");
|
||||
#endif
|
||||
@@ -3540,7 +3538,9 @@ void JSC__JSPromise__rejectOnNextTickWithHandled(JSC::JSPromise* promise, JSC::J
|
||||
value = jsUndefined();
|
||||
}
|
||||
|
||||
JSC::QueuedTask task { nullptr, JSC::InternalMicrotask::BunPerformMicrotaskJob, globalObject, microtaskFunction, rejectPromiseFunction, globalObject->m_asyncContextData.get()->getInternalField(0), promise, value };
|
||||
// BunPerformMicrotaskJob now handles async context directly:
|
||||
// arguments[0]: job function, arguments[1]: asyncContext, arguments[2]: promise, arguments[3]: value
|
||||
JSC::QueuedTask task { nullptr, JSC::InternalMicrotask::BunPerformMicrotaskJob, 0, globalObject, rejectPromiseFunction, asyncContext, promise, value };
|
||||
globalObject->vm().queueMicrotask(WTF::move(task));
|
||||
RETURN_IF_EXCEPTION(scope, );
|
||||
}
|
||||
@@ -5406,9 +5406,7 @@ extern "C" void JSC__JSGlobalObject__queueMicrotaskJob(JSC::JSGlobalObject* arg0
|
||||
if (microtaskArgs[3].isEmpty()) {
|
||||
microtaskArgs[3] = jsUndefined();
|
||||
}
|
||||
JSC::JSFunction* microTaskFunction = globalObject->performMicrotaskFunction();
|
||||
#if ASSERT_ENABLED
|
||||
ASSERT_WITH_MESSAGE(microTaskFunction, "Invalid microtask function");
|
||||
auto& vm = globalObject->vm();
|
||||
if (microtaskArgs[0].isCell()) {
|
||||
JSC::Integrity::auditCellFully(vm, microtaskArgs[0].asCell());
|
||||
@@ -5428,7 +5426,9 @@ extern "C" void JSC__JSGlobalObject__queueMicrotaskJob(JSC::JSGlobalObject* arg0
|
||||
|
||||
#endif
|
||||
|
||||
JSC::QueuedTask task { nullptr, JSC::InternalMicrotask::BunPerformMicrotaskJob, globalObject, microTaskFunction, WTF::move(microtaskArgs[0]), WTF::move(microtaskArgs[1]), WTF::move(microtaskArgs[2]), WTF::move(microtaskArgs[3]) };
|
||||
// BunPerformMicrotaskJob now handles async context directly:
|
||||
// arguments[0]: job function, arguments[1]: asyncContext, arguments[2-3]: optional args
|
||||
JSC::QueuedTask task { nullptr, JSC::InternalMicrotask::BunPerformMicrotaskJob, 0, globalObject, WTF::move(microtaskArgs[0]), WTF::move(microtaskArgs[1]), WTF::move(microtaskArgs[2]), WTF::move(microtaskArgs[3]) };
|
||||
globalObject->vm().queueMicrotask(WTF::move(task));
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ JSC_DECLARE_HOST_FUNCTION(jsVerifyOneShot);
|
||||
static const unsigned int NoDsaSignature = static_cast<unsigned int>(-1);
|
||||
|
||||
struct SignJobCtx {
|
||||
WTF_MAKE_TZONE_ALLOCATED(name);
|
||||
WTF_MAKE_TZONE_ALLOCATED(SignJobCtx);
|
||||
|
||||
public:
|
||||
enum class Mode {
|
||||
|
||||
@@ -37,40 +37,32 @@
|
||||
#include "SerializedScriptValue.h"
|
||||
// #include "WorkerOrWorkletGlobalScope.h"
|
||||
#include <JavaScriptCore/JSCJSValueInlines.h>
|
||||
#include <wtf/SortedArrayMap.h>
|
||||
|
||||
namespace WebCore {
|
||||
|
||||
using NavigationTimingFunction = unsigned long long (PerformanceTiming::*)() const;
|
||||
|
||||
static constexpr std::array<std::pair<ComparableASCIILiteral, NavigationTimingFunction>, 21> restrictedMarkMappings { {
|
||||
{ "connectEnd"_s, &PerformanceTiming::connectEnd },
|
||||
{ "connectStart"_s, &PerformanceTiming::connectStart },
|
||||
{ "domComplete"_s, &PerformanceTiming::domComplete },
|
||||
{ "domContentLoadedEventEnd"_s, &PerformanceTiming::domContentLoadedEventEnd },
|
||||
{ "domContentLoadedEventStart"_s, &PerformanceTiming::domContentLoadedEventStart },
|
||||
{ "domInteractive"_s, &PerformanceTiming::domInteractive },
|
||||
{ "domLoading"_s, &PerformanceTiming::domLoading },
|
||||
{ "domainLookupEnd"_s, &PerformanceTiming::domainLookupEnd },
|
||||
{ "domainLookupStart"_s, &PerformanceTiming::domainLookupStart },
|
||||
{ "fetchStart"_s, &PerformanceTiming::fetchStart },
|
||||
{ "loadEventEnd"_s, &PerformanceTiming::loadEventEnd },
|
||||
{ "loadEventStart"_s, &PerformanceTiming::loadEventStart },
|
||||
{ "navigationStart"_s, &PerformanceTiming::navigationStart },
|
||||
{ "redirectEnd"_s, &PerformanceTiming::redirectEnd },
|
||||
{ "redirectStart"_s, &PerformanceTiming::redirectStart },
|
||||
{ "requestStart"_s, &PerformanceTiming::requestStart },
|
||||
{ "responseEnd"_s, &PerformanceTiming::responseEnd },
|
||||
{ "responseStart"_s, &PerformanceTiming::responseStart },
|
||||
{ "secureConnectionStart"_s, &PerformanceTiming::secureConnectionStart },
|
||||
{ "unloadEventEnd"_s, &PerformanceTiming::unloadEventEnd },
|
||||
{ "unloadEventStart"_s, &PerformanceTiming::unloadEventStart },
|
||||
} };
|
||||
static constexpr SortedArrayMap restrictedMarkFunctions { restrictedMarkMappings };
|
||||
|
||||
bool PerformanceUserTiming::isRestrictedMarkName(const String& markName)
|
||||
{
|
||||
return restrictedMarkFunctions.contains(markName);
|
||||
return markName == "connectEnd"_s
|
||||
|| markName == "connectStart"_s
|
||||
|| markName == "domComplete"_s
|
||||
|| markName == "domContentLoadedEventEnd"_s
|
||||
|| markName == "domContentLoadedEventStart"_s
|
||||
|| markName == "domInteractive"_s
|
||||
|| markName == "domLoading"_s
|
||||
|| markName == "domainLookupEnd"_s
|
||||
|| markName == "domainLookupStart"_s
|
||||
|| markName == "fetchStart"_s
|
||||
|| markName == "loadEventEnd"_s
|
||||
|| markName == "loadEventStart"_s
|
||||
|| markName == "navigationStart"_s
|
||||
|| markName == "redirectEnd"_s
|
||||
|| markName == "redirectStart"_s
|
||||
|| markName == "requestStart"_s
|
||||
|| markName == "responseEnd"_s
|
||||
|| markName == "responseStart"_s
|
||||
|| markName == "secureConnectionStart"_s
|
||||
|| markName == "unloadEventEnd"_s
|
||||
|| markName == "unloadEventStart"_s;
|
||||
}
|
||||
|
||||
PerformanceUserTiming::PerformanceUserTiming(Performance& performance)
|
||||
|
||||
@@ -59,7 +59,6 @@
|
||||
#include <variant>
|
||||
#include <wtf/GetPtr.h>
|
||||
#include <wtf/PointerPreparations.h>
|
||||
#include <wtf/SortedArrayMap.h>
|
||||
#include <wtf/URL.h>
|
||||
|
||||
namespace WebCore {
|
||||
@@ -87,14 +86,12 @@ template<> JSString* convertEnumerationToJS(JSGlobalObject& lexicalGlobalObject,
|
||||
template<> std::optional<CryptoKey::Type> parseEnumeration<CryptoKey::Type>(JSGlobalObject& lexicalGlobalObject, JSValue value)
|
||||
{
|
||||
auto stringValue = value.toWTFString(&lexicalGlobalObject);
|
||||
static constexpr std::array<std::pair<ComparableASCIILiteral, CryptoKey::Type>, 3> mappings { {
|
||||
{ "private"_s, CryptoKey::Type::Private },
|
||||
{ "public"_s, CryptoKey::Type::Public },
|
||||
{ "secret"_s, CryptoKey::Type::Secret },
|
||||
} };
|
||||
static constexpr SortedArrayMap enumerationMapping { mappings };
|
||||
if (auto* enumerationValue = enumerationMapping.tryGet(stringValue); enumerationValue) [[likely]]
|
||||
return *enumerationValue;
|
||||
if (stringValue == "private"_s)
|
||||
return CryptoKey::Type::Private;
|
||||
if (stringValue == "public"_s)
|
||||
return CryptoKey::Type::Public;
|
||||
if (stringValue == "secret"_s)
|
||||
return CryptoKey::Type::Secret;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include <JavaScriptCore/JSCInlines.h>
|
||||
#include <JavaScriptCore/JSString.h>
|
||||
#include <wtf/NeverDestroyed.h>
|
||||
#include <wtf/SortedArrayMap.h>
|
||||
|
||||
namespace WebCore {
|
||||
using namespace JSC;
|
||||
@@ -64,19 +63,22 @@ template<> JSString* convertEnumerationToJS(JSGlobalObject& lexicalGlobalObject,
|
||||
template<> std::optional<CryptoKeyUsage> parseEnumeration<CryptoKeyUsage>(JSGlobalObject& lexicalGlobalObject, JSValue value)
|
||||
{
|
||||
auto stringValue = value.toWTFString(&lexicalGlobalObject);
|
||||
static constexpr std::array<std::pair<ComparableASCIILiteral, CryptoKeyUsage>, 8> mappings { {
|
||||
{ "decrypt"_s, CryptoKeyUsage::Decrypt },
|
||||
{ "deriveBits"_s, CryptoKeyUsage::DeriveBits },
|
||||
{ "deriveKey"_s, CryptoKeyUsage::DeriveKey },
|
||||
{ "encrypt"_s, CryptoKeyUsage::Encrypt },
|
||||
{ "sign"_s, CryptoKeyUsage::Sign },
|
||||
{ "unwrapKey"_s, CryptoKeyUsage::UnwrapKey },
|
||||
{ "verify"_s, CryptoKeyUsage::Verify },
|
||||
{ "wrapKey"_s, CryptoKeyUsage::WrapKey },
|
||||
} };
|
||||
static constexpr SortedArrayMap enumerationMapping { mappings };
|
||||
if (auto* enumerationValue = enumerationMapping.tryGet(stringValue); enumerationValue) [[likely]]
|
||||
return *enumerationValue;
|
||||
if (stringValue == "decrypt"_s)
|
||||
return CryptoKeyUsage::Decrypt;
|
||||
if (stringValue == "deriveBits"_s)
|
||||
return CryptoKeyUsage::DeriveBits;
|
||||
if (stringValue == "deriveKey"_s)
|
||||
return CryptoKeyUsage::DeriveKey;
|
||||
if (stringValue == "encrypt"_s)
|
||||
return CryptoKeyUsage::Encrypt;
|
||||
if (stringValue == "sign"_s)
|
||||
return CryptoKeyUsage::Sign;
|
||||
if (stringValue == "unwrapKey"_s)
|
||||
return CryptoKeyUsage::UnwrapKey;
|
||||
if (stringValue == "verify"_s)
|
||||
return CryptoKeyUsage::Verify;
|
||||
if (stringValue == "wrapKey"_s)
|
||||
return CryptoKeyUsage::WrapKey;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,6 @@
|
||||
#include <variant>
|
||||
#include <wtf/GetPtr.h>
|
||||
#include <wtf/PointerPreparations.h>
|
||||
#include <wtf/SortedArrayMap.h>
|
||||
#include <wtf/URL.h>
|
||||
#include "ErrorCode.h"
|
||||
|
||||
@@ -96,15 +95,14 @@ template<> JSString* convertEnumerationToJS(JSGlobalObject& lexicalGlobalObject,
|
||||
template<> std::optional<SubtleCrypto::KeyFormat> parseEnumeration<SubtleCrypto::KeyFormat>(JSGlobalObject& lexicalGlobalObject, JSValue value)
|
||||
{
|
||||
auto stringValue = value.toWTFString(&lexicalGlobalObject);
|
||||
static constexpr std::array<std::pair<ComparableASCIILiteral, SubtleCrypto::KeyFormat>, 4> mappings { {
|
||||
{ "jwk"_s, SubtleCrypto::KeyFormat::Jwk },
|
||||
{ "pkcs8"_s, SubtleCrypto::KeyFormat::Pkcs8 },
|
||||
{ "raw"_s, SubtleCrypto::KeyFormat::Raw },
|
||||
{ "spki"_s, SubtleCrypto::KeyFormat::Spki },
|
||||
} };
|
||||
static constexpr SortedArrayMap enumerationMapping { mappings };
|
||||
if (auto* enumerationValue = enumerationMapping.tryGet(stringValue); enumerationValue) [[likely]]
|
||||
return *enumerationValue;
|
||||
if (stringValue == "jwk"_s)
|
||||
return SubtleCrypto::KeyFormat::Jwk;
|
||||
if (stringValue == "pkcs8"_s)
|
||||
return SubtleCrypto::KeyFormat::Pkcs8;
|
||||
if (stringValue == "raw"_s)
|
||||
return SubtleCrypto::KeyFormat::Raw;
|
||||
if (stringValue == "spki"_s)
|
||||
return SubtleCrypto::KeyFormat::Spki;
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
|
||||
@@ -733,7 +733,6 @@ function emitConvertEnumFunction(w: CodeWriter, type: TypeImpl) {
|
||||
headers.add("JavaScriptCore/JSCInlines.h");
|
||||
headers.add("JavaScriptCore/JSString.h");
|
||||
headers.add("wtf/NeverDestroyed.h");
|
||||
headers.add("wtf/SortedArrayMap.h");
|
||||
|
||||
w.line(`String convertEnumerationToString(${name} enumerationValue) {`);
|
||||
w.indent();
|
||||
@@ -754,16 +753,10 @@ function emitConvertEnumFunction(w: CodeWriter, type: TypeImpl) {
|
||||
w.line();
|
||||
w.line(`template<> std::optional<${name}> parseEnumerationFromString<${name}>(const String& stringValue)`);
|
||||
w.line(`{`);
|
||||
w.line(
|
||||
` static constexpr std::array<std::pair<ComparableASCIILiteral, ${name}>, ${type.data.length}> mappings { {`,
|
||||
);
|
||||
for (const value of type.data) {
|
||||
w.line(` { ${str(value)}_s, ${name}::${pascal(value)} },`);
|
||||
w.line(` if (stringValue == ${str(value)}_s)`);
|
||||
w.line(` return ${name}::${pascal(value)};`);
|
||||
}
|
||||
w.line(` } };`);
|
||||
w.line(` static constexpr SortedArrayMap enumerationMapping { mappings };`);
|
||||
w.line(` if (auto* enumerationValue = enumerationMapping.tryGet(stringValue); enumerationValue) [[likely]]`);
|
||||
w.line(` return *enumerationValue;`);
|
||||
w.line(` return std::nullopt;`);
|
||||
w.line(`}`);
|
||||
w.line();
|
||||
|
||||
@@ -134,32 +134,20 @@ export function enumeration(
|
||||
}
|
||||
get cppSource() {
|
||||
const qualifiedName = "Bun::Bindgen::Generated::" + name;
|
||||
const pairType = `::std::pair<::WTF::ComparableASCIILiteral, ::${qualifiedName}>`;
|
||||
return reindent(`
|
||||
#include "root.h"
|
||||
#include "Generated${name}.h"
|
||||
#include <wtf/SortedArrayMap.h>
|
||||
|
||||
template<> std::optional<${qualifiedName}>
|
||||
WebCore::parseEnumerationFromString<${qualifiedName}>(const WTF::String& stringVal)
|
||||
{
|
||||
static constexpr ::std::array<${pairType}, ${valueMap.size}> mappings {
|
||||
${joinIndented(
|
||||
12,
|
||||
Array.from(valueMap.entries())
|
||||
.sort(([v1], [v2]) => (v1 < v2 ? -1 : 1))
|
||||
.map(([value, i]) => {
|
||||
return `${pairType} {
|
||||
${toASCIILiteral(value)},
|
||||
::${qualifiedName}::${cppMembers[i]},
|
||||
},`;
|
||||
}),
|
||||
)}
|
||||
};
|
||||
static constexpr ::WTF::SortedArrayMap enumerationMapping { mappings };
|
||||
if (auto* enumerationValue = enumerationMapping.tryGet(stringVal)) [[likely]] {
|
||||
return *enumerationValue;
|
||||
}
|
||||
${joinIndented(
|
||||
10,
|
||||
Array.from(valueMap.entries()).map(([value, i]) => {
|
||||
return `if (stringVal == ${toASCIILiteral(value)})
|
||||
return ::${qualifiedName}::${cppMembers[i]};`;
|
||||
}),
|
||||
)}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user