| 12258 | } |
| 12259 | |
| 12260 | void asCCompiler::ProcessDeferredParams(asCExprContext *ctx, bool processOnlyOutRef) |
| 12261 | { |
| 12262 | if( isProcessingDeferredParams ) return; |
| 12263 | |
| 12264 | isProcessingDeferredParams = true; |
| 12265 | |
| 12266 | for( asUINT n = 0; n < ctx->deferredParams.GetLength(); n++ ) |
| 12267 | { |
| 12268 | asSDeferredParam outParam = ctx->deferredParams[n]; |
| 12269 | if( !processOnlyOutRef && outParam.argInOutFlags < asTM_OUTREF ) // &in, or not reference |
| 12270 | { |
| 12271 | // Just release the variable |
| 12272 | ReleaseTemporaryVariable(outParam.argType, &ctx->bc); |
| 12273 | |
| 12274 | ctx->deferredParams.RemoveIndex(n--); |
| 12275 | } |
| 12276 | else if( outParam.argInOutFlags == asTM_OUTREF ) |
| 12277 | { |
| 12278 | // Assign the value returned in the output reference parameter to the expression passed as argument |
| 12279 | asCExprContext *expr = outParam.origExpr; |
| 12280 | outParam.origExpr = 0; |
| 12281 | |
| 12282 | if( outParam.argType.dataType.IsObjectHandle() ) |
| 12283 | { |
| 12284 | // Implicitly convert the value to a handle |
| 12285 | if( expr->type.dataType.IsObjectHandle() ) |
| 12286 | expr->type.isExplicitHandle = true; |
| 12287 | } |
| 12288 | |
| 12289 | // Verify that the expression result in a lvalue, or a property accessor |
| 12290 | if( IsLValue(expr->type) || expr->property_get || expr->property_set ) |
| 12291 | { |
| 12292 | asCExprContext rctx(engine); |
| 12293 | rctx.type = outParam.argType; |
| 12294 | if( rctx.type.dataType.IsPrimitive() ) |
| 12295 | rctx.type.dataType.MakeReference(false); |
| 12296 | else |
| 12297 | { |
| 12298 | rctx.bc.InstrSHORT(asBC_PSF, (short)outParam.argType.stackOffset); |
| 12299 | rctx.type.dataType.MakeReference(IsVariableOnHeap(outParam.argType.stackOffset)); |
| 12300 | if( expr->type.isExplicitHandle ) |
| 12301 | rctx.type.isExplicitHandle = true; |
| 12302 | } |
| 12303 | |
| 12304 | asCExprContext o(engine); |
| 12305 | DoAssignment(&o, expr, &rctx, outParam.argNode, outParam.argNode, ttAssignment, outParam.argNode); |
| 12306 | |
| 12307 | if( !o.type.dataType.IsPrimitive() ) o.bc.Instr(asBC_PopPtr); |
| 12308 | |
| 12309 | // The assignment may itself have resulted in a new temporary variable, e.g. if |
| 12310 | // the opAssign returns a non-reference. We must release this temporary variable |
| 12311 | // since it won't be used |
| 12312 | ReleaseTemporaryVariable(o.type, &o.bc); |
| 12313 | |
| 12314 | MergeExprBytecode(ctx, &o); |
| 12315 | } |
| 12316 | else |
| 12317 | { |
nothing calls this directly
no test coverage detected