diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2013-02-27 09:57:09 +0000 |
---|---|---|
committer | Simon Peyton Jones <simonpj@microsoft.com> | 2013-02-27 09:57:09 +0000 |
commit | 47d226544fc3fb11d024740a162f8ae4e1d044c9 (patch) | |
tree | 8a024b97de71216f6b3606d3cda7bf16ae1f98a6 /rts/Stable.c | |
parent | 7b5e514d85c086be8dc6d938b526c97b6ced56eb (diff) | |
parent | 0ee31659afe7a6819f9eb5e233f98e5592f1b439 (diff) | |
download | haskell-tc-arrows.tar.gz |
Merge remote-tracking branch 'origin/master' into tc-arrowstc-arrows
Diffstat (limited to 'rts/Stable.c')
-rw-r--r-- | rts/Stable.c | 46 |
1 files changed, 27 insertions, 19 deletions
diff --git a/rts/Stable.c b/rts/Stable.c index e1807faa72..0dade10105 100644 --- a/rts/Stable.c +++ b/rts/Stable.c @@ -278,28 +278,36 @@ freeStablePtr(StgStablePtr sp) /* * get at the real stuff...remove indirections. - * It untags pointers before dereferencing and - * retags the real stuff with its tag (if there - * is any) when returning. - * - * ToDo: move to a better home. */ -static -StgClosure* -removeIndirections(StgClosure* p) +static StgClosure* +removeIndirections (StgClosure* p) { - StgWord tag = GET_CLOSURE_TAG(p); - StgClosure* q = UNTAG_CLOSURE(p); - - while (get_itbl(q)->type == IND || - get_itbl(q)->type == IND_STATIC || - get_itbl(q)->type == IND_PERM) { - q = ((StgInd *)q)->indirectee; - tag = GET_CLOSURE_TAG(q); - q = UNTAG_CLOSURE(q); - } + StgClosure* q; + + while (1) + { + q = UNTAG_CLOSURE(p); + + switch (get_itbl(q)->type) { + case IND: + case IND_STATIC: + case IND_PERM: + p = ((StgInd *)q)->indirectee; + continue; + + case BLACKHOLE: + p = ((StgInd *)q)->indirectee; + if (GET_CLOSURE_TAG(p) != 0) { + continue; + } else { + break; + } - return TAG_CLOSURE(tag,q); + default: + break; + } + return p; + } } StgWord |