void callFuncDllVariant(FuncAndToken *aFuncAndToken) { Func &func = *(aFuncAndToken->mFunc); ExprTokenType & aResultToken = aFuncAndToken->mToken ; // Func &func = *(Func *)g_script.mTempFunc ; if (!INTERRUPTIBLE_IN_EMERGENCY) return; if (g_nThreads >= g_MaxThreadsTotal) // Below: Only a subset of ACT_IS_ALWAYS_ALLOWED is done here because: // 1) The omitted action types seem too obscure to grant always-run permission for msg-monitor events. // 2) Reduction in code size. if (g_nThreads >= MAX_THREADS_EMERGENCY // To avoid array overflow, this limit must by obeyed except where otherwise documented. || func.mJumpToLine->mActionType != ACT_EXITAPP && func.mJumpToLine->mActionType != ACT_RELOAD) return; // Need to check if backup is needed in case script explicitly called the function rather than using // it solely as a callback. UPDATE: And now that max_instances is supported, also need it for that. // See ExpandExpression() for detailed comments about the following section. VarBkp *var_backup = NULL; // If needed, it will hold an array of VarBkp objects. int var_backup_count; // The number of items in the above array. if (func.mInstances > 0) // Backup is needed. if (!Var::BackupFunctionVars(func, var_backup, var_backup_count)) // Out of memory. return; // Since we're in the middle of processing messages, and since out-of-memory is so rare, // it seems justifiable not to have any error reporting and instead just avoid launching // the new thread. // Since above didn't return, the launch of the new thread is now considered unavoidable. // See MsgSleep() for comments about the following section. TCHAR ErrorLevel_saved[ERRORLEVEL_SAVED_SIZE]; tcslcpy(ErrorLevel_saved, g_ErrorLevel->Contents(), _countof(ErrorLevel_saved)); InitNewThread(0, false, true, func.mJumpToLine->mActionType); // v1.0.38.04: Below was added to maximize responsiveness to incoming messages. The reasoning // is similar to why the same thing is done in MsgSleep() prior to its launch of a thread, so see // MsgSleep for more comments: g_script.mLastScriptRest = g_script.mLastPeekTime = GetTickCount(); DEBUGGER_STACK_PUSH(func.mJumpToLine, func.mName) // ExprTokenType aResultToken; // ExprTokenType &aResultToken = aResultToken_to_return ; func.Call(&aResultToken); // Call the UDF. TokenToVariant(aResultToken, aFuncAndToken->variant_to_return_dll); DEBUGGER_STACK_POP() ResumeUnderlyingThread(ErrorLevel_saved); return; }
HRESULT __stdcall CoCOMServer::ahkgetvar(/*in*/VARIANT name,/*[in,optional]*/ VARIANT getVar,/*out*/VARIANT *result) { USES_CONVERSION; if (result==NULL) return ERROR_INVALID_PARAMETER; //USES_CONVERSION; TCHAR buf[MAX_INTEGER_SIZE]; Var *var; ExprTokenType aToken ; var = g_script.FindVar(name.vt == VT_BSTR ? OLE2T(name.bstrVal) : Variant2T(name,buf)) ; var->TokenToContents(aToken) ; VariantInit(result); // CComVariant b ; VARIANT b ; TokenToVariant(aToken, b); return VariantCopy(result, &b) ; // return S_OK ; // return b.Detach(result); }