Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: exception handling rework: unwind argument as integer. #271

Merged
merged 1 commit into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 21 additions & 28 deletions clang/lib/CodeGen/CGException.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,12 @@ static llvm::FunctionCallee getSehTryEndFn(CodeGenModule &CGM) {
static llvm::FunctionCallee getUnexpectedFn(CodeGenModule &CGM) {
// void __cxa_call_unexpected(void *thrown_exception);

llvm::Type* ArgTy = CGM.Int8PtrTy;
if (CGM.getLangOpts().Cheerp) {
ArgTy = CGM.Int32Ty;
}
llvm::FunctionType *FTy =
llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, /*isVarArg=*/false);
llvm::FunctionType::get(CGM.VoidTy, ArgTy, /*isVarArg=*/false);

return CGM.CreateRuntimeFunction(FTy, "__cxa_call_unexpected");
}
Expand Down Expand Up @@ -96,8 +100,12 @@ llvm::FunctionCallee CodeGenModule::getTerminateFn() {

static llvm::FunctionCallee getCatchallRethrowFn(CodeGenModule &CGM,
StringRef Name) {
llvm::Type* ArgTy = CGM.Int8PtrTy;
if (CGM.getLangOpts().Cheerp) {
ArgTy = CGM.Int32Ty;
}
llvm::FunctionType *FTy =
llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, /*isVarArg=*/false);
llvm::FunctionType::get(CGM.VoidTy, ArgTy, /*isVarArg=*/false);

return CGM.CreateRuntimeFunction(FTy, Name);
}
Expand Down Expand Up @@ -460,9 +468,13 @@ void CodeGenFunction::EmitTypedPtrExprToExn(const Expr *e, Address addr) {


Address CodeGenFunction::getExceptionSlot() {
llvm::Type* Ty = Int8PtrTy;
if(CGM.getLangOpts().Cheerp) {
Ty = Int32Ty;
}
if (!ExceptionSlot)
ExceptionSlot = CreateTempAlloca(Int8PtrTy, "exn.slot");
return Address(ExceptionSlot, Int8PtrTy, getPointerAlign());
ExceptionSlot = CreateTempAlloca(Ty, "exn.slot");
return Address(ExceptionSlot, Ty, getPointerAlign());
}

Address CodeGenFunction::getEHSelectorSlot() {
Expand Down Expand Up @@ -878,14 +890,6 @@ llvm::BasicBlock *CodeGenFunction::EmitLandingPad() {
LPadInst = Builder.CreateLandingPad(LPadTy, 0);

llvm::Value *LPadExn = Builder.CreateExtractValue(LPadInst, 0);
if(!CGM.getTarget().isByteAddressable()) {
if (CGM.getTarget().getTriple().isCheerpWasm()) {
LPadExn = Builder.CreateIntToPtr(LPadExn, Int8PtrTy);
} else {
llvm::Function *MakeReg = CGM.getIntrinsic(llvm::Intrinsic::cheerp_make_regular, {Int8PtrTy, Int8PtrTy});
LPadExn = Builder.CreateCall(MakeReg, {llvm::ConstantPointerNull::get(Int8PtrTy), LPadExn});
}
}
Builder.CreateStore(LPadExn, getExceptionSlot());
llvm::Value *LPadSel = Builder.CreateExtractValue(LPadInst, 1);
Builder.CreateStore(LPadSel, getEHSelectorSlot());
Expand Down Expand Up @@ -1538,6 +1542,11 @@ void CodeGenFunction::FinallyInfo::exit(CodeGenFunction &CGF) {
// If there's a begin-catch function, call it.
if (BeginCatchFn) {
exn = CGF.getExceptionFromSlot();
// In Cheerp Exn has type int, but the ObjC runtime expects void*.
// Just add an inttoptr here, we are doing it just to pass tests
if (CGF.getLangOpts().Cheerp && CGF.getLangOpts().ObjC) {
exn = CGF.Builder.CreateIntToPtr(exn, CGF.VoidPtrTy);
}
CGF.EmitNounwindRuntimeCall(BeginCatchFn, exn);
}

Expand Down Expand Up @@ -1584,14 +1593,6 @@ llvm::BasicBlock *CodeGenFunction::getTerminateLandingPad() {
llvm::Value *Exn = nullptr;
if (getLangOpts().CPlusPlus) {
Exn = Builder.CreateExtractValue(LPadInst, 0);
if(!CGM.getTarget().isByteAddressable()) {
if (CGM.getTarget().getTriple().isCheerpWasm()) {
Exn = Builder.CreateIntToPtr(Exn, Int8PtrTy);
} else {
llvm::Function *MakeReg = CGM.getIntrinsic(llvm::Intrinsic::cheerp_make_regular, {Int8PtrTy, Int8PtrTy});
Exn = Builder.CreateCall(MakeReg, {llvm::ConstantPointerNull::get(Int8PtrTy), Exn});
}
}
}
llvm::CallInst *terminateCall =
CGM.getCXXABI().emitTerminateForUnexpectedException(*this, Exn);
Expand Down Expand Up @@ -1692,14 +1693,6 @@ llvm::BasicBlock *CodeGenFunction::getEHResumeBlock(bool isCleanup) {

llvm::Type *LPadType = GetLandingPadTy();
llvm::Value *LPadVal = llvm::UndefValue::get(LPadType);
if (!CGM.getTarget().isByteAddressable()) {
if (CGM.getTarget().getTriple().isCheerpWasm()) {
Exn = Builder.CreatePtrToInt(Exn, Int32Ty);
} else {
llvm::Function *PtrOffset = CGM.getIntrinsic(llvm::Intrinsic::cheerp_pointer_offset, {Int8PtrTy});
Exn = Builder.CreateCall(PtrOffset, Exn);
}
}
LPadVal = Builder.CreateInsertValue(LPadVal, Exn, 0, "lpad.val");
LPadVal = Builder.CreateInsertValue(LPadVal, Sel, 1, "lpad.val");
Builder.CreateResume(LPadVal);
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/CodeGen/CGObjCRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,11 @@ void CGObjCRuntime::EmitTryCatchStmt(CodeGenFunction &CGF,
}

llvm::Value *RawExn = CGF.getExceptionFromSlot();
// In Cheerp Exn has type int, but the ObjC runtime expects void*.
// Just add an inttoptr here, we are doing it just to pass tests
if (CGM.getLangOpts().Cheerp) {
RawExn = CGF.Builder.CreateIntToPtr(RawExn, CGM.VoidPtrTy);
}

// Enter the catch.
llvm::Value *Exn = RawExn;
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CodeGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -2010,7 +2010,7 @@ class CodeGenFunction : public CodeGenTypeCache {

/// Get the named landingpad/resume type (Cheerp)
llvm::StructType* GetLandingPadTy() {
if (getTarget().isByteAddressable()) {
if(!getLangOpts().Cheerp) {
return llvm::StructType::get(Int8PtrTy, Int32Ty);
}
auto* Ret = llvm::StructType::getTypeByName(CGM.getLLVMContext(), "struct._ZN10__cxxabiv119__cheerp_landingpadE");
Expand Down
43 changes: 33 additions & 10 deletions clang/lib/CodeGen/ItaniumCXXABI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4823,12 +4823,20 @@ void ItaniumCXXABI::emitCXXStructor(GlobalDecl GD) {
}
}

static llvm::FunctionCallee getBeginCatchFn(CodeGenModule &CGM) {
static llvm::FunctionCallee getBeginCatchFn(CodeGenModule &CGM, bool asmjs) {
llvm::Type* RetTy = CGM.Int8PtrTy;
llvm::Type* ArgTy = CGM.Int8PtrTy;
const char* name = "__cxa_begin_catch";
if (CGM.getLangOpts().Cheerp) {
ArgTy = CGM.Int32Ty;
if (asmjs)
name = "__cxa_begin_catch_wasm";
}
// void *__cxa_begin_catch(void*);
llvm::FunctionType *FTy = llvm::FunctionType::get(
CGM.Int8PtrTy, CGM.Int8PtrTy, /*isVarArg=*/false);
RetTy, ArgTy, /*isVarArg=*/false);

return CGM.CreateRuntimeFunction(FTy, "__cxa_begin_catch");
return CGM.CreateRuntimeFunction(FTy, name);
}

static llvm::FunctionCallee getEndCatchFn(CodeGenModule &CGM) {
Expand All @@ -4839,12 +4847,20 @@ static llvm::FunctionCallee getEndCatchFn(CodeGenModule &CGM) {
return CGM.CreateRuntimeFunction(FTy, "__cxa_end_catch");
}

static llvm::FunctionCallee getGetExceptionPtrFn(CodeGenModule &CGM) {
static llvm::FunctionCallee getGetExceptionPtrFn(CodeGenModule &CGM, bool asmjs) {
llvm::Type* RetTy = CGM.Int8PtrTy;
llvm::Type* ArgTy = CGM.Int8PtrTy;
const char* name = "__cxa_get_exception_ptr";
if (CGM.getLangOpts().Cheerp) {
ArgTy = CGM.Int32Ty;
if (asmjs)
name = "__cxa_get_exception_ptr_wasm";
}
// void *__cxa_get_exception_ptr(void*);
llvm::FunctionType *FTy = llvm::FunctionType::get(
CGM.Int8PtrTy, CGM.Int8PtrTy, /*isVarArg=*/false);
RetTy, ArgTy, /*isVarArg=*/false);

return CGM.CreateRuntimeFunction(FTy, "__cxa_get_exception_ptr");
return CGM.CreateRuntimeFunction(FTy, name);
}

namespace {
Expand Down Expand Up @@ -4882,8 +4898,9 @@ namespace {
static llvm::Value *CallBeginCatch(CodeGenFunction &CGF,
llvm::Value *Exn,
bool EndMightThrow) {
bool asmjs = CGF.CurFn->getSection() == "asmjs";
llvm::CallInst *call =
CGF.EmitNounwindRuntimeCall(getBeginCatchFn(CGF.CGM), Exn);
CGF.EmitNounwindRuntimeCall(getBeginCatchFn(CGF.CGM, asmjs), Exn);

CGF.EHStack.pushCleanup<CallEndCatch>(NormalAndEHCleanup, EndMightThrow);

Expand Down Expand Up @@ -5035,10 +5052,11 @@ static void InitCatchParam(CodeGenFunction &CGF,
return;
}

bool asmjs = CGF.CurFn->getSection() == "asmjs";
// We have to call __cxa_get_exception_ptr to get the adjusted
// pointer before copying.
llvm::CallInst *rawAdjustedExn =
CGF.EmitNounwindRuntimeCall(getGetExceptionPtrFn(CGF.CGM), Exn);
CGF.EmitNounwindRuntimeCall(getGetExceptionPtrFn(CGF.CGM, asmjs), Exn);

// Cast that to the appropriate type.
Address adjustedExn(CGF.Builder.CreateBitCast(rawAdjustedExn, PtrTy),
Expand Down Expand Up @@ -5116,8 +5134,13 @@ void ItaniumCXXABI::emitBeginCatch(CodeGenFunction &CGF,
/// This code is used only in C++.
static llvm::FunctionCallee getClangCallTerminateFn(CodeGenModule &CGM) {
ASTContext &C = CGM.getContext();
bool asmjs = CGM.getTriple().isCheerpWasm();
CanQualType ArgTy = C.getPointerType(C.CharTy);
if (CGM.getLangOpts().Cheerp) {
ArgTy = C.IntTy;
}
const CGFunctionInfo &FI = CGM.getTypes().arrangeBuiltinFunctionDeclaration(
C.VoidTy, {C.getPointerType(C.CharTy)});
C.VoidTy, {ArgTy});
llvm::FunctionType *fnTy = CGM.getTypes().GetFunctionType(FI);
llvm::FunctionCallee fnRef = CGM.CreateRuntimeFunction(
fnTy, "__clang_call_terminate", llvm::AttributeList(), /*Local=*/true);
Expand Down Expand Up @@ -5149,7 +5172,7 @@ static llvm::FunctionCallee getClangCallTerminateFn(CodeGenModule &CGM) {
llvm::Value *exn = &*fn->arg_begin();

// Call __cxa_begin_catch(exn).
llvm::CallInst *catchCall = builder.CreateCall(getBeginCatchFn(CGM), exn);
llvm::CallInst *catchCall = builder.CreateCall(getBeginCatchFn(CGM, asmjs), exn);
catchCall->setDoesNotThrow();
catchCall->setCallingConv(CGM.getRuntimeCC());

Expand Down
7 changes: 6 additions & 1 deletion compiler-rt/lib/asan/asan_interceptors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -349,8 +349,13 @@ extern "C" void __cxa_throw_wasm(void *a, void *b, void *c) {
#endif


#ifdef __CHEERP__
#define UNWIND_ARG_TYPE int
#else
#define UNWIND_ARG_TYPE void*
#endif
#if ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION
INTERCEPTOR(void, __cxa_rethrow_primary_exception, void *a) {
INTERCEPTOR(void, __cxa_rethrow_primary_exception, UNWIND_ARG_TYPE a) {
__asan_handle_no_return();
REAL(__cxa_rethrow_primary_exception)(a);
}
Expand Down
2 changes: 1 addition & 1 deletion compiler-rt/lib/asan/asan_interceptors.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ DECLARE_REAL(size_t, mbstowcs, wchar_t *dest, const char *src, size_t len);
DECLARE_REAL(size_t, mbsrtowcs, wchar_t *dest, const char **src, size_t len, void *ps);

extern "C" void __cheerp___cxa_throw(void *, void *, void *);
extern "C" void __cheerp___cxa_rethrow_primary_exception(void*);
extern "C" void __cheerp___cxa_rethrow_primary_exception(int);
#endif // SANITIZER_CHEERPWASM

# if !SANITIZER_APPLE
Expand Down
9 changes: 7 additions & 2 deletions libcxx/include/exception
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,12 @@ _LIBCPP_NORETURN _LIBCPP_FUNC_VIS void rethrow_exception(exception_ptr);

class _LIBCPP_TYPE_VIS exception_ptr
{
void* __ptr_;
#ifdef __CHEERP__
unsigned
#else
void*
#endif
__ptr_;
public:
_LIBCPP_INLINE_VISIBILITY exception_ptr() _NOEXCEPT : __ptr_() {}
_LIBCPP_INLINE_VISIBILITY exception_ptr(nullptr_t) _NOEXCEPT : __ptr_() {}
Expand All @@ -197,7 +202,7 @@ public:
~exception_ptr() _NOEXCEPT;

_LIBCPP_INLINE_VISIBILITY explicit operator bool() const _NOEXCEPT
{return __ptr_ != nullptr;}
{return __ptr_ != 0;}

friend _LIBCPP_INLINE_VISIBILITY
bool operator==(const exception_ptr& __x, const exception_ptr& __y) _NOEXCEPT
Expand Down
2 changes: 1 addition & 1 deletion libcxx/src/support/runtime/exception_pointer_cxxabi.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ _LIBCPP_NORETURN
void
nested_exception::rethrow_nested() const
{
if (__ptr_ == nullptr)
if (__ptr_ == 0)
terminate();
rethrow_exception(__ptr_);
}
Expand Down
14 changes: 10 additions & 4 deletions libcxxabi/include/cxxabi.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,15 +146,21 @@ extern _LIBCXXABI_FUNC_VIS char *__cxa_demangle(const char *mangled_name,
char *output_buffer,
size_t *length, int *status);

#ifdef __CHEERP__
#define UNWIND_TY int
#else
#define UNWIND_TY void*
#endif

// Apple additions to support C++ 0x exception_ptr class
// These are primitives to wrap a smart pointer around an exception object
extern _LIBCXXABI_FUNC_VIS void *__cxa_current_primary_exception() throw();
extern _LIBCXXABI_FUNC_VIS UNWIND_TY __cxa_current_primary_exception() throw();
extern _LIBCXXABI_FUNC_VIS void
__cxa_rethrow_primary_exception(void *primary_exception);
__cxa_rethrow_primary_exception(UNWIND_TY primary_exception);
extern _LIBCXXABI_FUNC_VIS void
__cxa_increment_exception_refcount(void *primary_exception) throw();
__cxa_increment_exception_refcount(UNWIND_TY primary_exception) throw();
extern _LIBCXXABI_FUNC_VIS void
__cxa_decrement_exception_refcount(void *primary_exception) throw();
__cxa_decrement_exception_refcount(UNWIND_TY primary_exception) throw();

// Apple extension to support std::uncaught_exception()
extern _LIBCXXABI_FUNC_VIS bool __cxa_uncaught_exception() throw();
Expand Down
Loading
Loading