| 1043 | } |
| 1044 | |
| 1045 | vec4f pinvoke_impl3 ( Context & context, SimNode_CallBase * call, vec4f * args ) { |
| 1046 | auto invCtx = cast<Context *>::to(args[0]); |
| 1047 | if ( !invCtx ) context.throw_error_at(call->debugInfo, "pinvoke with null context"); |
| 1048 | auto fn = cast<Lambda>::to(args[1]); |
| 1049 | SimFunction ** fnMnh = (SimFunction **)fn.capture; |
| 1050 | if (!fnMnh) context.throw_error_at(call->debugInfo, "invoke null lambda"); |
| 1051 | SimFunction * simFn = *fnMnh; |
| 1052 | if ( !simFn ) context.throw_error_at(call->debugInfo, "pinvoke can't find function #%p", (void*)simFn); |
| 1053 | if ( simFn->debugInfo->count!=uint32_t(call->nArguments-1) ) context.throw_error_at(call->debugInfo, |
| 1054 | "pinvoke function expects %u arguments, but %u provided", simFn->debugInfo->count, call->nArguments-2); |
| 1055 | if ( !invCtx->contextMutex ) context.throw_error_at(call->debugInfo,"threadlock_context is not set"); |
| 1056 | vec4f res = v_zero(); |
| 1057 | LineInfo exAt; |
| 1058 | string exText; |
| 1059 | invCtx->threadlock_context([&](){ |
| 1060 | invCtx->exception = nullptr; |
| 1061 | if ( !invCtx->ownStack ) { |
| 1062 | StackAllocator sharedStack(8*1024); |
| 1063 | SharedStackGuard guard(*invCtx, sharedStack); |
| 1064 | invCtx->runWithCatch([&](){ |
| 1065 | res = invCtx->callOrFastcall(simFn, args+1, &call->debugInfo); |
| 1066 | }); |
| 1067 | } else { |
| 1068 | invCtx->runWithCatch([&](){ |
| 1069 | res = invCtx->callOrFastcall(simFn, args+1, &call->debugInfo); |
| 1070 | }); |
| 1071 | } |
| 1072 | if ( invCtx->exception ) { |
| 1073 | exAt = invCtx->exceptionAt; |
| 1074 | exText = invCtx->exception; |
| 1075 | } |
| 1076 | }); |
| 1077 | if ( !exText.empty() ) context.throw_error_at(exAt, "%s", exText.c_str()); |
| 1078 | return res; |
| 1079 | } |
| 1080 | |
| 1081 | // invoke_debug_agent_method("category","function",....) |
| 1082 |
nothing calls this directly
no test coverage detected