| 10852 | |
| 10853 | |
| 10854 | ResultType Line::PerformLoopFor(ResultToken *aResultToken, Line *&aJumpToLine, Line *aUntil) |
| 10855 | { |
| 10856 | ResultType result; |
| 10857 | Line *jump_to_line; |
| 10858 | global_struct &g = *::g; // Might slightly speed up the loop below. |
| 10859 | |
| 10860 | ResultToken enum_token; |
| 10861 | enum_token.InitResult(nullptr); // buf can be null because this isn't ACT_RETURN. |
| 10862 | PRIVATIZE_S_DEREF_BUF; |
| 10863 | result = ExpandSingleArg(mArgc - 1, enum_token, our_deref_buf, our_deref_buf_size); |
| 10864 | DEPRIVATIZE_S_DEREF_BUF; |
| 10865 | if (result != OK) |
| 10866 | // A script-function-call inside the expression returned EARLY_EXIT or FAIL. |
| 10867 | return result; |
| 10868 | |
| 10869 | int var_count = mArgc - 1; |
| 10870 | |
| 10871 | IObject *enumerator; |
| 10872 | result = GetEnumerator(enumerator, enum_token, var_count, true); |
| 10873 | enum_token.Free(); |
| 10874 | if (result == FAIL || result == EARLY_EXIT) |
| 10875 | return result; |
| 10876 | |
| 10877 | // "Localize" the loop variables. |
| 10878 | auto var_bkp = (VarBkp *)_alloca(sizeof(VarBkp) * var_count); |
| 10879 | auto var_param = (ExprTokenType**)_alloca(sizeof(ExprTokenType*) * var_count); |
| 10880 | for (int i = 0; i < var_count; ++i) |
| 10881 | { |
| 10882 | ExprTokenType &token = *(ExprTokenType*)_alloca(sizeof(ExprTokenType)); |
| 10883 | var_param[i] = &token; |
| 10884 | if (mArg[i].type == ARG_TYPE_OUTPUT_VAR) |
| 10885 | { |
| 10886 | auto var = VAR(mArg[i]); |
| 10887 | var->Backup(var_bkp[i]); |
| 10888 | token.symbol = SYM_OBJECT; |
| 10889 | token.object = var->GetRef(); |
| 10890 | if (token.object) |
| 10891 | continue; |
| 10892 | result = FAIL; |
| 10893 | var_count = i + 1; // Restore var_bkp and free any previous refs. |
| 10894 | } |
| 10895 | // Omitted. |
| 10896 | token.symbol = SYM_MISSING; |
| 10897 | token.marker = _T(""); |
| 10898 | token.marker_length = 0; |
| 10899 | } |
| 10900 | |
| 10901 | // Now that the enumerator expression has been evaluated, init A_Index: |
| 10902 | g.mLoopIteration = 1; |
| 10903 | |
| 10904 | if (result != FAIL) |
| 10905 | for (result = CONDITION_FALSE;; ++g.mLoopIteration) |
| 10906 | { |
| 10907 | auto enum_result = CallEnumerator(enumerator, var_param, var_count, true); |
| 10908 | if (enum_result == FAIL || enum_result == EARLY_EXIT) |
| 10909 | { |
| 10910 | result = enum_result; |
| 10911 | break; |
no test coverage detected