summaryrefslogtreecommitdiff
path: root/rts/Interpreter.c
diff options
context:
space:
mode:
authorBen Gamari <bgamari.foss@gmail.com>2017-06-27 10:26:01 -0400
committerBen Gamari <ben@smart-cactus.org>2017-06-27 12:55:06 -0400
commit9ef909db5ed3dc45fc1acdb608ad3f1896362966 (patch)
tree142e728dfb0c0a3a5519bb045d95f0e02dacc1e3 /rts/Interpreter.c
parent914962ca23e407efdd3429dc89adcca7bee15f28 (diff)
downloadhaskell-9ef909db5ed3dc45fc1acdb608ad3f1896362966.tar.gz
Allow bytecode interpreter to make unsafe foreign calls
Reviewers: austin, hvr, erikd, simonmar Reviewed By: simonmar Subscribers: rwbarton, thomie GHC Trac Issues: #8281, #13730. Differential Revision: https://phabricator.haskell.org/D3619
Diffstat (limited to 'rts/Interpreter.c')
-rw-r--r--rts/Interpreter.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/rts/Interpreter.c b/rts/Interpreter.c
index 1a883a5b4b..92914735a7 100644
--- a/rts/Interpreter.c
+++ b/rts/Interpreter.c
@@ -1598,7 +1598,9 @@ run_BCO:
void *tok;
int stk_offset = BCO_NEXT;
int o_itbl = BCO_GET_LARGE_ARG;
- int interruptible = BCO_NEXT;
+ int flags = BCO_NEXT;
+ bool interruptible = flags & 0x1;
+ bool unsafe_call = flags & 0x2;
void(*marshall_fn)(void*) = (void (*)(void*))BCO_LIT(o_itbl);
/* the stack looks like this:
@@ -1686,15 +1688,19 @@ run_BCO:
Sp[1] = (W_)obj;
Sp[0] = (W_)&stg_ret_p_info;
- SAVE_THREAD_STATE();
- tok = suspendThread(&cap->r, interruptible);
+ if (!unsafe_call) {
+ SAVE_THREAD_STATE();
+ tok = suspendThread(&cap->r, interruptible);
+ }
// We already made a copy of the arguments above.
ffi_call(cif, fn, ret, argptrs);
// And restart the thread again, popping the stg_ret_p frame.
- cap = (Capability *)((void *)((unsigned char*)resumeThread(tok) - STG_FIELD_OFFSET(Capability,r)));
- LOAD_THREAD_STATE();
+ if (!unsafe_call) {
+ cap = (Capability *)((void *)((unsigned char*)resumeThread(tok) - STG_FIELD_OFFSET(Capability,r)));
+ LOAD_THREAD_STATE();
+ }
if (Sp[0] != (W_)&stg_ret_p_info) {
// the stack is not how we left it. This probably