|
9 | 9 | #include "ir/function.h"
|
10 | 10 | #include "ir/instruction.h"
|
11 | 11 |
|
| 12 | +#include "frontend.h" |
12 | 13 | #include "gluecode.h"
|
13 | 14 | #include "platform.h"
|
14 | 15 |
|
@@ -918,11 +919,32 @@ namespace interp
|
918 | 919 |
|
919 | 920 |
|
920 | 921 |
|
| 922 | + static void complainAboutFFIEscape(void* fnptr, fir::Type* fnty, const std::string& name) |
| 923 | + { |
| 924 | + if(frontend::getCanFFIEscape()) |
| 925 | + return; |
921 | 926 |
|
| 927 | + BareError* e = 0; |
| 928 | + if(name.empty()) |
| 929 | + { |
| 930 | + e = BareError::make("interp: cannot call external function (name unavailable; symbol address %p, function type '%s')", |
| 931 | + fnptr, fnty->str()); |
| 932 | + } |
| 933 | + else |
| 934 | + { |
| 935 | + e = BareError::make("interp: cannot call external function '%s'", name); |
| 936 | + } |
| 937 | + |
| 938 | + e->append(BareError::make(MsgType::Note, "to call external functions (ffi), pass '--ffi-escape' as a command-line flag")); |
| 939 | + e->postAndQuit(); |
| 940 | + } |
922 | 941 |
|
923 | 942 |
|
924 |
| - static interp::Value runFunctionWithLibFFI(InterpState* is, void* fnptr, fir::FunctionType* fnty, const std::vector<interp::Value>& args) |
| 943 | + static interp::Value runFunctionWithLibFFI(InterpState* is, void* fnptr, fir::FunctionType* fnty, const std::vector<interp::Value>& args, |
| 944 | + const std::string& nameIfAvailable = "") |
925 | 945 | {
|
| 946 | + complainAboutFFIEscape(fnptr, fnty, nameIfAvailable); |
| 947 | + |
926 | 948 | // we are assuming the values in 'args' are correct!
|
927 | 949 | ffi_type** arg_types = new ffi_type*[args.size()];
|
928 | 950 | {
|
@@ -998,15 +1020,15 @@ namespace interp
|
998 | 1020 | void* fnptr = platform::compiler::getSymbol(fn->getName().str());
|
999 | 1021 | if(!fnptr) error("interp: failed to find symbol named '%s'\n", fn->getName().str());
|
1000 | 1022 |
|
1001 |
| - return runFunctionWithLibFFI(is, fnptr, fn->getType(), args); |
| 1023 | + return runFunctionWithLibFFI(is, fnptr, fn->getType(), args, /* name: */ fn->getName().str()); |
1002 | 1024 | }
|
1003 | 1025 |
|
1004 | 1026 | static interp::Value runFunctionWithLibFFI(InterpState* is, const interp::Function& fn, const std::vector<interp::Value>& args)
|
1005 | 1027 | {
|
1006 | 1028 | void* fnptr = platform::compiler::getSymbol(fn.func->getName().str());
|
1007 | 1029 | if(!fnptr) error("interp: failed to find symbol named '%s'\n", fn.func->getName().str());
|
1008 | 1030 |
|
1009 |
| - return runFunctionWithLibFFI(is, fnptr, fn.func->getType(), args); |
| 1031 | + return runFunctionWithLibFFI(is, fnptr, fn.func->getType(), args, /* name: */ fn.extFuncName); |
1010 | 1032 | }
|
1011 | 1033 |
|
1012 | 1034 |
|
@@ -1134,7 +1156,8 @@ namespace interp
|
1134 | 1156 | else
|
1135 | 1157 | error("interp: call to function pointer with invalid type '%s'", targ.type);
|
1136 | 1158 |
|
1137 |
| - is->stackFrames.back().values[res.callResultValue] = runFunctionWithLibFFI(is, (void*) ptr, fnty, res.callArguments); |
| 1159 | + is->stackFrames.back().values[res.callResultValue] = runFunctionWithLibFFI(is, (void*) ptr, fnty, res.callArguments, |
| 1160 | + /* name: */ res.callTarget->extFuncName); |
1138 | 1161 | i += 1;
|
1139 | 1162 | }
|
1140 | 1163 | } break;
|
|
0 commit comments