| 5770 | } |
| 5771 | |
| 5772 | ResultType Script::DefineFunc(LPTSTR aBuf, bool aStatic, bool aIsInExpression) |
| 5773 | // Returns OK or FAIL. |
| 5774 | // Caller has already called ValidateName() on the function, and it is known that this valid name |
| 5775 | // is followed immediately by an open-paren. aFuncExceptionVar is the address of an array on |
| 5776 | // the caller's stack that will hold the list of exception variables (those that must be explicitly |
| 5777 | // declared as either local or global) within the body of the function. |
| 5778 | { |
| 5779 | LPTSTR param_end, param_start = _tcschr(aBuf, '('); // Caller has ensured that this will return non-NULL. |
| 5780 | int insert_pos; |
| 5781 | |
| 5782 | auto last_hotfunc = mLastHotFunc; |
| 5783 | if (last_hotfunc) |
| 5784 | { |
| 5785 | // This means we are defining a function under a "trigger::". |
| 5786 | // Then mLastHotFunc will not be used, instead all variants which have set it as its |
| 5787 | // mJumpLabel will replace it with the new function defined in this call. |
| 5788 | ASSERT(last_hotfunc == g->CurrentFunc); |
| 5789 | g->CurrentFunc = // To avoid nesting the new function inside it. |
| 5790 | mLastHotFunc = nullptr; // To avoid the next call AddLine demanding a ACT_BLOCK_BEGIN. |
| 5791 | } |
| 5792 | |
| 5793 | bool is_method = mClassObjectCount && !g->CurrentFunc && !aIsInExpression; |
| 5794 | if (is_method) // Class method or property getter/setter. |
| 5795 | { |
| 5796 | Object *class_object = mClassObject[mClassObjectCount - 1]; |
| 5797 | if (!aStatic) |
| 5798 | class_object = (Object *)class_object->GetOwnPropObj(_T("Prototype")); |
| 5799 | |
| 5800 | *param_start = '\0'; // Temporarily terminate, for simplicity. |
| 5801 | |
| 5802 | // Build the fully-qualified method name for A_ThisFunc and ListVars: |
| 5803 | // AddFunc() enforces a limit of MAX_VAR_NAME_LENGTH characters for function names, which is relied |
| 5804 | // on by FindFunc(), BIF_OnMessage() and perhaps others. For simplicity, allow one extra char to be |
| 5805 | // printed and rely on AddFunc() detecting that the name is too long. |
| 5806 | TCHAR full_name[MAX_VAR_NAME_LENGTH + 1 + 1]; // Extra +1 for null terminator. |
| 5807 | _sntprintf(full_name, MAX_VAR_NAME_LENGTH + 1, aStatic ? _T("%s.%s") : _T("%s.Prototype.%s"), mClassName, aBuf); |
| 5808 | full_name[MAX_VAR_NAME_LENGTH + 1] = '\0'; // Must terminate at this exact point if _sntprintf hit the limit. |
| 5809 | |
| 5810 | *param_start = '('; // Undo temporary termination. |
| 5811 | |
| 5812 | // Below passes class_object for AddFunc() to store the func "by reference" in it: |
| 5813 | if ( !(g->CurrentFunc = AddFunc(full_name, -1, class_object)) ) |
| 5814 | return FAIL; |
| 5815 | } |
| 5816 | else |
| 5817 | { |
| 5818 | // The value of g->CurrentFunc must be set here rather than by our caller since AddVar(), which we call, |
| 5819 | // relies upon it having been done. |
| 5820 | if ( !(g->CurrentFunc = AddFunc(aBuf, param_start - aBuf)) ) |
| 5821 | return FAIL; // It already displayed the error. |
| 5822 | } |
| 5823 | |
| 5824 | auto &func = *g->CurrentFunc; // For performance and convenience. |
| 5825 | |
| 5826 | size_t param_length, value_length; |
| 5827 | FuncParam param[MAX_FUNCTION_PARAMS]; |
| 5828 | int param_count = 0; |
| 5829 | TCHAR buf[LINE_SIZE], *target; |
nothing calls this directly
no test coverage detected