From 22e37a5c8da976e2002adac4a4960bb64e9d44a5 Mon Sep 17 00:00:00 2001 From: Jarred Sumner Date: Thu, 8 Aug 2024 22:49:26 -0700 Subject: [PATCH] Add more debug exception checks (#13188) --- src/bun.js/bindings/bindings.cpp | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/bun.js/bindings/bindings.cpp b/src/bun.js/bindings/bindings.cpp index d1cb9566b5..956b8ca191 100644 --- a/src/bun.js/bindings/bindings.cpp +++ b/src/bun.js/bindings/bindings.cpp @@ -1,6 +1,8 @@ + #include "root.h" +#include "JavaScriptCore/ThrowScope.h" #include "JavaScriptCore/JSCast.h" #include "JavaScriptCore/JSType.h" #include "JavaScriptCore/NumberObject.h" @@ -227,6 +229,12 @@ enum class AsymmetricMatcherConstructorType : uint8_t { InstanceOf = 9, }; +#if ASSERT_ENABLED +#define ASSERT_NO_PENDING_EXCEPTION(globalObject) DECLARE_THROW_SCOPE(globalObject->vm()).assertNoExceptionExceptTermination() +#else +#define ASSERT_NO_PENDING_EXCEPTION(globalObject) void() +#endif + extern "C" bool Expect_readFlagsAndProcessPromise(JSC__JSValue instanceValue, JSC__JSGlobalObject* globalObject, ExpectFlags* flags, JSC__JSValue* value, AsymmetricMatcherConstructorType* constructorType); extern "C" uint8_t AsymmetricMatcherConstructorType__fromJS(JSC__JSGlobalObject* globalObject, JSC__JSValue encodedValue) @@ -1568,6 +1576,8 @@ WebCore__FetchHeaders* WebCore__FetchHeaders__createFromJS(JSC__JSGlobalObject* JSC__JSValue WebCore__FetchHeaders__toJS(WebCore__FetchHeaders* headers, JSC__JSGlobalObject* lexicalGlobalObject) { Zig::GlobalObject* globalObject = reinterpret_cast(lexicalGlobalObject); + ASSERT_NO_PENDING_EXCEPTION(globalObject); + bool needsMemoryCost = headers->hasOneRef(); JSValue value = WebCore::toJS(lexicalGlobalObject, globalObject, headers); @@ -1852,6 +1862,7 @@ BunString WebCore__DOMURL__fileSystemPath(WebCore__DOMURL* arg0) extern "C" JSC__JSValue ZigString__toJSONObject(const ZigString* strPtr, JSC::JSGlobalObject* globalObject) { + ASSERT_NO_PENDING_EXCEPTION(globalObject); auto str = Zig::toString(*strPtr); auto scope = DECLARE_THROW_SCOPE(globalObject->vm()); @@ -1884,7 +1895,7 @@ void JSGlobalObject__throwOutOfMemoryError(JSC::JSGlobalObject* globalObject) JSC__JSValue SystemError__toErrorInstance(const SystemError* arg0, JSC__JSGlobalObject* globalObject) { - + ASSERT_NO_PENDING_EXCEPTION(globalObject); SystemError err = *arg0; JSC::VM& vm = globalObject->vm(); @@ -2185,6 +2196,7 @@ bool JSC__JSFunction__getSourceCode(JSC__JSValue JSValue0, ZigString* outSourceC void JSC__JSValue__jsonStringify(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1, uint32_t arg2, BunString* arg3) { + ASSERT_NO_PENDING_EXCEPTION(arg1); JSC::JSValue value = JSC::JSValue::decode(JSValue0); WTF::String str = JSC::JSONStringify(arg1, value, (unsigned)arg2); *arg3 = Bun::toStringRef(str); @@ -2327,6 +2339,7 @@ bool JSC__JSValue__isSameValue(JSC__JSValue JSValue0, JSC__JSValue JSValue1, bool JSC__JSValue__deepEquals(JSC__JSValue JSValue0, JSC__JSValue JSValue1, JSC__JSGlobalObject* globalObject) { + ASSERT_NO_PENDING_EXCEPTION(globalObject); JSValue v1 = JSValue::decode(JSValue0); JSValue v2 = JSValue::decode(JSValue1); @@ -2513,6 +2526,7 @@ size_t JSC__JSObject__getArrayLength(JSC__JSObject* arg0) { return arg0->getArra JSC__JSValue JSC__JSObject__getIndex(JSC__JSValue jsValue, JSC__JSGlobalObject* arg1, uint32_t arg3) { + ASSERT_NO_PENDING_EXCEPTION(arg1); return JSC::JSValue::encode(JSC::JSValue::decode(jsValue).toObject(arg1)->getIndex(arg1, arg3)); } @@ -2725,7 +2739,7 @@ JSC__JSValue JSC__JSValue__values(JSC__JSGlobalObject* globalObject, JSC__JSValu bool JSC__JSValue__asArrayBuffer_(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1, Bun__ArrayBuffer* arg2) { - + ASSERT_NO_PENDING_EXCEPTION(arg1); JSC::JSValue value = JSC::JSValue::decode(JSValue0); if (UNLIKELY(!value) || !value.isCell()) { return false; @@ -3723,7 +3737,7 @@ JSC__JSValue JSC__JSValue__getIfPropertyExistsImpl(JSC__JSValue JSValue0, JSC__JSGlobalObject* globalObject, const unsigned char* arg1, uint32_t arg2) { - + ASSERT_NO_PENDING_EXCEPTION(globalObject); JSValue value = JSC::JSValue::decode(JSValue0); ASSERT_WITH_MESSAGE(!value.isEmpty(), "get() must not be called on empty value"); @@ -3742,6 +3756,7 @@ JSC__JSValue JSC__JSValue__getIfPropertyExistsImpl(JSC__JSValue JSValue0, extern "C" JSC__JSValue JSC__JSValue__getIfPropertyExistsImplString(JSC__JSValue JSValue0, JSC__JSGlobalObject* globalObject, BunString* propertyName) { + ASSERT_NO_PENDING_EXCEPTION(globalObject); JSValue value = JSC::JSValue::decode(JSValue0); if (UNLIKELY(!value.isObject())) return JSValue::encode({}); @@ -3757,6 +3772,8 @@ extern "C" JSC__JSValue JSC__JSValue__getIfPropertyExistsImplString(JSC__JSValue extern "C" JSC__JSValue JSC__JSValue__getOwn(JSC__JSValue JSValue0, JSC__JSGlobalObject* globalObject, BunString* propertyName) { + ASSERT_NO_PENDING_EXCEPTION(globalObject); + VM& vm = globalObject->vm(); JSValue value = JSC::JSValue::decode(JSValue0); WTF::String propertyNameString = propertyName->tag == BunStringTag::Empty ? WTF::String(""_s) : propertyName->toWTFString(BunString::ZeroCopy); @@ -3771,6 +3788,7 @@ extern "C" JSC__JSValue JSC__JSValue__getOwn(JSC__JSValue JSValue0, JSC__JSGloba JSC__JSValue JSC__JSValue__getIfPropertyExistsFromPath(JSC__JSValue JSValue0, JSC__JSGlobalObject* globalObject, JSC__JSValue arg1) { + ASSERT_NO_PENDING_EXCEPTION(globalObject); VM& vm = globalObject->vm(); ThrowScope scope = DECLARE_THROW_SCOPE(vm); JSValue value = JSValue::decode(JSValue0); @@ -3940,6 +3958,7 @@ int32_t JSC__JSValue__toInt32(JSC__JSValue JSValue0) CPP_DECL double JSC__JSValue__coerceToDouble(JSC__JSValue JSValue0, JSC__JSGlobalObject* arg1) { + ASSERT_NO_PENDING_EXCEPTION(arg1); JSC::JSValue value = JSC::JSValue::decode(JSValue0); auto catchScope = DECLARE_CATCH_SCOPE(arg1->vm()); double result = value.toNumber(arg1); @@ -4007,6 +4026,7 @@ JSC__JSString* JSC__JSValue__toStringOrNull(JSC__JSValue JSValue0, JSC__JSGlobal bool JSC__JSValue__toMatch(JSC__JSValue regexValue, JSC__JSGlobalObject* global, JSC__JSValue value) { + ASSERT_NO_PENDING_EXCEPTION(global); JSC::JSValue regex = JSC::JSValue::decode(regexValue); JSC::JSValue str = JSC::JSValue::decode(value); if (regex.asCell()->type() != RegExpObjectType || !str.isString()) { @@ -5100,6 +5120,7 @@ bool JSC__JSValue__toBooleanSlow(JSC__JSValue JSValue0, JSC__JSGlobalObject* glo template static void JSC__JSValue__forEachPropertyImpl(JSC__JSValue JSValue0, JSC__JSGlobalObject* globalObject, void* arg2, void (*iter)(JSC__JSGlobalObject* arg0, void* ctx, ZigString* arg2, JSC__JSValue JSValue3, bool isSymbol, bool isPrivateSymbol)) { + ASSERT_NO_PENDING_EXCEPTION(globalObject); JSC::JSValue value = JSC::JSValue::decode(JSValue0); JSC::JSObject* object = value.getObject(); if (!object)