Commit 123e4528 authored by Simon Marlow's avatar Simon Marlow

Load the target of a dynamic foreign call into a temporary

Fixes ffi011(opt) on x86_64.  I don't know why this has only just
appeared today, it's apparently been broken for some time.
parent 30f7fffb
......@@ -110,13 +110,14 @@ emitForeignCall' safety results target args vols
| otherwise = do
id <- newTemp wordRep
temp_args <- load_args_into_temps args
temp_target <- load_target_into_temp target
emitSaveThreadState
stmtC (CmmCall (CmmForeignCall suspendThread CCallConv)
[(id,PtrHint)]
[ (CmmReg (CmmGlobal BaseReg), PtrHint) ]
vols
)
stmtC (CmmCall target results temp_args vols)
stmtC (CmmCall temp_target results temp_args vols)
stmtC (CmmCall (CmmForeignCall resumeThread CCallConv)
[ (CmmGlobal BaseReg, PtrHint) ]
-- Assign the result to BaseReg: we
......@@ -139,16 +140,25 @@ resumeThread = CmmLit (CmmLabel (mkRtsCodeLabel SLIT("resumeThread")))
--
-- This is a HACK; really it should be done in the back end, but
-- it's easier to generate the temporaries here.
load_args_into_temps args = mapM maybe_assignTemp args
load_args_into_temps = mapM arg_assign_temp
where arg_assign_temp (e,hint) = do
tmp <- maybe_assign_temp e
return (tmp,hint)
maybe_assignTemp (e, hint)
| hasNoGlobalRegs e = return (e, hint)
load_target_into_temp (CmmForeignCall expr conv) = do
tmp <- maybe_assign_temp expr
return (CmmForeignCall tmp conv)
load_target_info_temp other_target =
return other_target
maybe_assign_temp e
| hasNoGlobalRegs e = return e
| otherwise = do
-- don't use assignTemp, it uses its own notion of "trivial"
-- expressions, which are wrong here
reg <- newTemp (cmmExprRep e)
stmtC (CmmAssign reg e)
return (CmmReg reg, hint)
return (CmmReg reg)
-- -----------------------------------------------------------------------------
-- Save/restore the thread state in the TSO
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment