Interface
| 5114 | |
| 5115 | // Interface |
| 5116 | bool asCContext::IsVarInScope(asUINT varIndex, asUINT stackLevel) |
| 5117 | { |
| 5118 | // Don't return anything if there is no bytecode, e.g. before calling Execute() |
| 5119 | if( m_regs.programPointer == 0 ) return false; |
| 5120 | |
| 5121 | if( stackLevel >= GetCallstackSize() ) return false; |
| 5122 | |
| 5123 | asCScriptFunction *func; |
| 5124 | asUINT pos; |
| 5125 | |
| 5126 | if( stackLevel == 0 ) |
| 5127 | { |
| 5128 | func = m_currentFunction; |
| 5129 | if( func->scriptData == 0 ) return false; |
| 5130 | pos = asUINT(m_regs.programPointer - func->scriptData->byteCode.AddressOf()); |
| 5131 | } |
| 5132 | else |
| 5133 | { |
| 5134 | asPWORD *s = m_callStack.AddressOf() + (GetCallstackSize()-stackLevel-1)*CALLSTACK_FRAME_SIZE; |
| 5135 | func = (asCScriptFunction*)s[1]; |
| 5136 | if( func->scriptData == 0 ) return false; |
| 5137 | pos = asUINT((asDWORD*)s[2] - func->scriptData->byteCode.AddressOf()); |
| 5138 | } |
| 5139 | |
| 5140 | // First determine if the program position is after the variable declaration |
| 5141 | if( func->scriptData->variables.GetLength() <= varIndex ) return false; |
| 5142 | if( func->scriptData->variables[varIndex]->declaredAtProgramPos > pos ) return false; |
| 5143 | |
| 5144 | asUINT declaredAt = func->scriptData->variables[varIndex]->declaredAtProgramPos; |
| 5145 | |
| 5146 | // If the program position is after the variable declaration it is necessary |
| 5147 | // determine if the program position is still inside the statement block where |
| 5148 | // the variable was declared. |
| 5149 | bool foundVarDecl = false; |
| 5150 | |
| 5151 | // Temporary variables aren't explicitly declared, they are just reserved slots available throughout the function call. |
| 5152 | // So we'll consider that the variable declaration is found at the very beginning |
| 5153 | if (func->scriptData->variables[varIndex]->name.GetLength() == 0) |
| 5154 | foundVarDecl = true; |
| 5155 | |
| 5156 | for( int n = 0; n < (int)func->scriptData->objVariableInfo.GetLength(); n++ ) |
| 5157 | { |
| 5158 | // Find the varDecl |
| 5159 | if( func->scriptData->objVariableInfo[n].programPos >= declaredAt ) |
| 5160 | { |
| 5161 | // skip instructions at the same program position, but before the varDecl. |
| 5162 | // Note, varDecl will only be in the objVariableInfo for object types |
| 5163 | if (func->scriptData->objVariableInfo[n].programPos == declaredAt && |
| 5164 | !foundVarDecl && |
| 5165 | func->scriptData->objVariableInfo[n].option != asOBJ_VARDECL) |
| 5166 | continue; |
| 5167 | |
| 5168 | foundVarDecl = true; |
| 5169 | |
| 5170 | // If the current block ends between the declaredAt and current |
| 5171 | // program position, then we know the variable is no longer visible |
| 5172 | int level = 0; |
| 5173 | for( ; n < (int)func->scriptData->objVariableInfo.GetLength(); n++ ) |