| 12203 | } |
| 12204 | |
| 12205 | void asCCompiler::AfterFunctionCall(int funcID, asCArray<asCExprContext*> &args, asCExprContext *ctx, bool deferAll) |
| 12206 | { |
| 12207 | // deferAll is set to true if for example the function returns a reference, since in |
| 12208 | // this case the function might be returning a reference to one of the arguments. |
| 12209 | |
| 12210 | asCScriptFunction *descr = builder->GetFunctionDescription(funcID); |
| 12211 | |
| 12212 | // Parameters that are sent by reference should be assigned |
| 12213 | // to the evaluated expression if it is an lvalue |
| 12214 | |
| 12215 | // Evaluate the arguments from last to first |
| 12216 | int n = (int)args.GetLength() - 1; |
| 12217 | for( ; n >= 0; n-- ) |
| 12218 | { |
| 12219 | asUINT realParamIdx = n; |
| 12220 | if (descr->IsVariadic() && n >= (int)descr->parameterTypes.GetLength() - 1) |
| 12221 | realParamIdx = descr->parameterTypes.GetLength() - 1; |
| 12222 | |
| 12223 | // All &out arguments must be deferred, except if the argument is clean, in which case the actual reference was passed in to the function |
| 12224 | // If deferAll is set all objects passed by reference or handle must be deferred |
| 12225 | if( (descr->parameterTypes[realParamIdx].IsReference() && (descr->inOutFlags[realParamIdx] & asTM_OUTREF) && !args[realParamIdx]->isCleanArg) || |
| 12226 | (descr->parameterTypes[realParamIdx].IsObject() && deferAll && (descr->parameterTypes[realParamIdx].IsReference() || descr->parameterTypes[realParamIdx].IsObjectHandle())) ) |
| 12227 | { |
| 12228 | asASSERT( !(descr->parameterTypes[realParamIdx].IsReference() && (descr->inOutFlags[realParamIdx] == asTM_OUTREF) && !args[realParamIdx]->isCleanArg) || args[realParamIdx]->origExpr ); |
| 12229 | |
| 12230 | // For &inout, only store the argument if it is for a temporary variable |
| 12231 | if( engine->ep.allowUnsafeReferences || |
| 12232 | descr->inOutFlags[realParamIdx] != asTM_INOUTREF || args[realParamIdx]->type.isTemporary ) |
| 12233 | { |
| 12234 | // Store the argument for later processing |
| 12235 | asSDeferredParam outParam; |
| 12236 | outParam.argNode = args[n]->exprNode; |
| 12237 | outParam.argType = args[n]->type; |
| 12238 | outParam.argInOutFlags = descr->inOutFlags[realParamIdx]; |
| 12239 | outParam.origExpr = args[n]->origExpr; |
| 12240 | |
| 12241 | ctx->deferredParams.PushLast(outParam); |
| 12242 | } |
| 12243 | } |
| 12244 | else |
| 12245 | { |
| 12246 | // Release the temporary variable now |
| 12247 | ReleaseTemporaryVariable(args[n]->type, &ctx->bc); |
| 12248 | } |
| 12249 | |
| 12250 | // Move the argument's deferred expressions over to the final expression |
| 12251 | for( asUINT m = 0; m < args[n]->deferredParams.GetLength(); m++ ) |
| 12252 | { |
| 12253 | ctx->deferredParams.PushLast(args[n]->deferredParams[m]); |
| 12254 | args[n]->deferredParams[m].origExpr = 0; |
| 12255 | } |
| 12256 | args[n]->deferredParams.SetLength(0); |
| 12257 | } |
| 12258 | } |
| 12259 | |
| 12260 | void asCCompiler::ProcessDeferredParams(asCExprContext *ctx, bool processOnlyOutRef) |
| 12261 | { |
nothing calls this directly
no test coverage detected