| 5679 | } |
| 5680 | |
| 5681 | void asCCompiler::CompileWhileStatement(asCScriptNode *wnode, asCByteCode *bc) |
| 5682 | { |
| 5683 | // Add a variable scope that will be used by CompileBreak/Continue to know where to stop deallocating variables |
| 5684 | AddVariableScope(true, true); |
| 5685 | |
| 5686 | // We will use two labels for the while loop |
| 5687 | int beforeLabel = nextLabel++; |
| 5688 | int afterLabel = nextLabel++; |
| 5689 | |
| 5690 | continueLabels.PushLast(beforeLabel); |
| 5691 | breakLabels.PushLast(afterLabel); |
| 5692 | |
| 5693 | // Add label before the expression |
| 5694 | bc->Label((short)beforeLabel); |
| 5695 | |
| 5696 | // Compile expression |
| 5697 | asCExprContext expr(engine); |
| 5698 | int r = CompileAssignment(wnode->firstChild, &expr); |
| 5699 | if( r == 0 ) |
| 5700 | { |
| 5701 | if (ProcessPropertyGetAccessor(&expr, wnode) < 0) |
| 5702 | return; |
| 5703 | |
| 5704 | // If turned on, allow the compiler to use either 'bool opImplConv()' or 'bool opConv()' on the type |
| 5705 | if (engine->ep.boolConversionMode == 1) |
| 5706 | ImplicitConversion(&expr, asCDataType::CreatePrimitive(ttBool, false), wnode->firstChild, asIC_EXPLICIT_VAL_CAST); |
| 5707 | // else, allow value types to be converted to bool using 'bool opImplConv()' |
| 5708 | else if (expr.type.dataType.GetTypeInfo() && (expr.type.dataType.GetTypeInfo()->GetFlags() & asOBJ_VALUE)) |
| 5709 | ImplicitConversion(&expr, asCDataType::CreatePrimitive(ttBool, false), wnode->firstChild, asIC_IMPLICIT_CONV); |
| 5710 | |
| 5711 | if (!expr.type.dataType.IsEqualExceptRefAndConst(asCDataType::CreatePrimitive(ttBool, true))) |
| 5712 | { |
| 5713 | asCString str; |
| 5714 | str.Format(TXT_EXPR_MUST_BE_BOOL_s, expr.type.dataType.Format(outFunc->nameSpace).AddressOf()); |
| 5715 | Error(str, wnode->firstChild); |
| 5716 | } |
| 5717 | else |
| 5718 | { |
| 5719 | ConvertToVariable(&expr); |
| 5720 | ProcessDeferredParams(&expr); |
| 5721 | |
| 5722 | // Jump to end of statement if expression is false |
| 5723 | expr.bc.InstrSHORT(asBC_CpyVtoR4, (short)expr.type.stackOffset); |
| 5724 | expr.bc.Instr(asBC_ClrHi); |
| 5725 | expr.bc.InstrDWORD(asBC_JZ, afterLabel); |
| 5726 | ReleaseTemporaryVariable(expr.type, &expr.bc); |
| 5727 | |
| 5728 | expr.bc.OptimizeLocally(tempVariableOffsets); |
| 5729 | bc->AddCode(&expr.bc); |
| 5730 | } |
| 5731 | } |
| 5732 | |
| 5733 | // Add a suspend bytecode inside the loop to guarantee |
| 5734 | // that the application can suspend the execution |
| 5735 | bc->Instr(asBC_SUSPEND); |
| 5736 | bc->InstrPTR(asBC_JitEntry, 0); |
| 5737 | |
| 5738 | // Compile statement |
nothing calls this directly
no test coverage detected