CInt r;
StgTSO_flags(CurrentTSO) = StgTSO_flags(CurrentTSO) &
- ~(TSO_BLOCKEX::I32|TSO_INTERRUPTIBLE::I32);
+ %lobits32(~(TSO_BLOCKEX|TSO_INTERRUPTIBLE));
/* Eagerly raise a blocked exception, if there is one */
if (StgTSO_blocked_exceptions(CurrentTSO) != END_TSO_QUEUE) {
INFO_TABLE_RET( stg_blockAsyncExceptionszh_ret, RET_SMALL )
{
- StgTSO_flags(CurrentTSO) =
- StgTSO_flags(CurrentTSO) | TSO_BLOCKEX::I32 | TSO_INTERRUPTIBLE::I32;
+ StgTSO_flags(CurrentTSO) = %lobits32(
+ TO_W_(StgTSO_flags(CurrentTSO)) | TSO_BLOCKEX | TSO_INTERRUPTIBLE);
Sp_adj(1);
jump %ENTRY_CODE(Sp(0));
if ((TO_W_(StgTSO_flags(CurrentTSO)) & TSO_BLOCKEX) == 0) {
- StgTSO_flags(CurrentTSO) =
- StgTSO_flags(CurrentTSO) | TSO_BLOCKEX::I32 | TSO_INTERRUPTIBLE::I32;
+ StgTSO_flags(CurrentTSO) = %lobits32(
+ TO_W_(StgTSO_flags(CurrentTSO)) | TSO_BLOCKEX | TSO_INTERRUPTIBLE);
/* avoid growing the stack unnecessarily */
if (Sp(0) == stg_blockAsyncExceptionszh_ret_info) {
/* If exceptions are already unblocked, there's nothing to do */
if ((TO_W_(StgTSO_flags(CurrentTSO)) & TSO_BLOCKEX) != 0) {
- StgTSO_flags(CurrentTSO) = StgTSO_flags(CurrentTSO) &
- ~(TSO_BLOCKEX::I32|TSO_INTERRUPTIBLE::I32);
+ StgTSO_flags(CurrentTSO) = %lobits32(
+ TO_W_(StgTSO_flags(CurrentTSO)) & ~(TSO_BLOCKEX|TSO_INTERRUPTIBLE));
/* avoid growing the stack unnecessarily */
if (Sp(0) == stg_unblockAsyncExceptionszh_ret_info) {
/* Needs 3 words because throwToSingleThreaded uses some stack */
STK_CHK_GEN( WDS(3), R1_PTR & R2_PTR, stg_killThreadzh);
+ /* We call allocate in throwTo(), so better check for GC */
+ MAYBE_GC(R1_PTR & R2_PTR, stg_killThreadzh);
/*
* We might have killed ourselves. In which case, better be *very*
}
} else {
W_ out;
- W_ retcode;
+ W_ msg;
out = Sp - WDS(1); /* ok to re-use stack space here */
- (retcode) = foreign "C" throwTo(MyCapability() "ptr",
- CurrentTSO "ptr",
- target "ptr",
- exception "ptr",
- out "ptr") [R1,R2];
+ (msg) = foreign "C" throwTo(MyCapability() "ptr",
+ CurrentTSO "ptr",
+ target "ptr",
+ exception "ptr") [R1,R2];
- switch [THROWTO_SUCCESS .. THROWTO_BLOCKED] (retcode) {
-
- case THROWTO_SUCCESS: {
+ if (msg == NULL) {
jump %ENTRY_CODE(Sp(0));
- }
-
- case THROWTO_BLOCKED: {
- R3 = W_[out];
- // we must block, and call throwToReleaseTarget() before returning
+ } else {
+ StgTSO_why_blocked(CurrentTSO) = BlockedOnMsgThrowTo;
+ StgTSO_block_info(CurrentTSO) = msg;
+ // we must block, and unlock the message before returning
jump stg_block_throwto;
}
- }
}
}
W_ r;
trec = StgTSO_trec(CurrentTSO);
(r) = foreign "C" stmValidateNestOfTransactions(trec "ptr") [];
- ("ptr" outer) = foreign "C" stmGetEnclosingTRec(trec "ptr") [];
+ outer = StgTRecHeader_enclosing_trec(trec);
foreign "C" stmAbortTransaction(MyCapability() "ptr", trec "ptr") [];
foreign "C" stmFreeAbortedTRec(MyCapability() "ptr", trec "ptr") [];
} else {
W_ trec, outer;
trec = StgTSO_trec(CurrentTSO);
- ("ptr" outer) = foreign "C" stmGetEnclosingTRec(trec "ptr") [];
+ outer = StgTRecHeader_enclosing_trec(trec);
foreign "C" stmAbortTransaction(MyCapability() "ptr", trec "ptr") [];
foreign "C" stmFreeAbortedTRec(MyCapability() "ptr", trec "ptr") [];
StgTSO_trec(CurrentTSO) = outer;
/* Ensure that async excpetions are blocked when running the handler.
*/
- StgTSO_flags(CurrentTSO) =
- StgTSO_flags(CurrentTSO) | TSO_BLOCKEX::I32 | TSO_INTERRUPTIBLE::I32;
+ StgTSO_flags(CurrentTSO) = %lobits32(
+ TO_W_(StgTSO_flags(CurrentTSO)) | TSO_BLOCKEX | TSO_INTERRUPTIBLE);
/* Call the handler, passing the exception value and a realworld
* token as arguments.