fix bugs found by exception scope verification (#20285)

Co-authored-by: 190n <7763597+190n@users.noreply.github.com>
This commit is contained in:
190n
2025-06-18 23:08:19 -07:00
committed by GitHub
parent aa37ecb7a5
commit 346e97dde2
98 changed files with 4263 additions and 933 deletions

View File

@@ -358,7 +358,7 @@ static JSValue handleVirtualModuleResult(
case OnLoadResultTypeCode: {
Bun__transpileVirtualModule(globalObject, specifier, referrer, &onLoadResult.value.sourceText.string, onLoadResult.value.sourceText.loader, res);
if (!res->success) {
return reject(JSValue::decode(reinterpret_cast<EncodedJSValue>(res->result.err.ptr)));
return reject(JSValue::decode(res->result.err.value));
}
auto provider = Zig::SourceProvider::create(globalObject, res->result.value);
@@ -434,20 +434,23 @@ extern "C" void Bun__onFulfillAsyncModule(
JSC::JSInternalPromise* promise = jsCast<JSC::JSInternalPromise*>(JSC::JSValue::decode(encodedPromiseValue));
if (!res->success) {
throwException(scope, res->result.err, globalObject);
auto* exception = scope.exception();
scope.clearException();
return promise->reject(globalObject, exception);
return promise->reject(globalObject, JSValue::decode(res->result.err.value));
}
auto specifierValue = Bun::toJS(globalObject, *specifier);
if (auto entry = globalObject->esmRegistryMap()->get(globalObject, specifierValue)) {
auto* map = globalObject->esmRegistryMap();
RETURN_IF_EXCEPTION(scope, );
auto entry = map->get(globalObject, specifierValue);
RETURN_IF_EXCEPTION(scope, );
if (entry) {
if (entry.isObject()) {
auto* object = entry.getObject();
if (auto state = object->getIfPropertyExists(globalObject, Bun::builtinNames(vm).statePublicName())) {
if (state.toInt32(globalObject) > JSC::JSModuleLoader::Status::Fetch) {
auto state = object->getIfPropertyExists(globalObject, Bun::builtinNames(vm).statePublicName());
RETURN_IF_EXCEPTION(scope, );
if (state && state.isInt32()) {
if (state.asInt32() > JSC::JSModuleLoader::Status::Fetch) {
// it's a race! we lost.
// https://github.com/oven-sh/bun/issues/6946
// https://github.com/oven-sh/bun/issues/12910
@@ -463,12 +466,15 @@ extern "C" void Bun__onFulfillAsyncModule(
promise->resolve(globalObject, code);
} else {
auto* exception = scope.exception();
scope.clearException();
promise->reject(globalObject, exception);
if (!vm.isTerminationException(exception)) {
scope.clearException();
promise->reject(globalObject, exception);
}
}
} else {
auto&& provider = Zig::SourceProvider::create(jsDynamicCast<Zig::GlobalObject*>(globalObject), res->result.value);
promise->resolve(globalObject, JSC::JSSourceCode::create(vm, JSC::SourceCode(provider)));
scope.assertNoExceptionExceptTermination();
}
} else {
// the module has since been deleted from the registry.
@@ -659,7 +665,9 @@ JSValue fetchCommonJSModule(
}
}
if (auto builtin = fetchBuiltinModuleWithoutResolution(globalObject, &specifier, res)) {
auto builtin = fetchBuiltinModuleWithoutResolution(globalObject, &specifier, res);
RETURN_IF_EXCEPTION(scope, {});
if (builtin) {
if (!res->success) {
RELEASE_AND_RETURN(scope, builtin);
}
@@ -708,18 +716,22 @@ JSValue fetchCommonJSModule(
JSMap* registry = globalObject->esmRegistryMap();
const auto hasAlreadyLoadedESMVersionSoWeShouldntTranspileItTwice = [&]() -> bool {
bool hasAlreadyLoadedESMVersionSoWeShouldntTranspileItTwice = [&]() -> bool {
JSValue entry = registry->get(globalObject, specifierValue);
if (!entry || !entry.isObject()) {
return false;
}
// return value doesn't matter since we check for exceptions after calling this lambda and
// before checking the returned bool
RETURN_IF_EXCEPTION(scope, false);
int status = entry.getObject()->getDirect(vm, WebCore::clientData(vm)->builtinNames().statePublicName()).asInt32();
return status > JSModuleLoader::Status::Fetch;
};
}();
RETURN_IF_EXCEPTION(scope, {});
if (hasAlreadyLoadedESMVersionSoWeShouldntTranspileItTwice()) {
if (hasAlreadyLoadedESMVersionSoWeShouldntTranspileItTwice) {
RELEASE_AND_RETURN(scope, jsNumber(-1));
}
return fetchCommonJSModuleNonBuiltin<false>(bunVM, vm, globalObject, &specifier, specifierValue, referrer, typeAttribute, res, target, specifierWtfString, BunLoaderTypeNone, scope);