| 5757 | } |
| 5758 | |
| 5759 | void asCCompiler::CompileDoWhileStatement(asCScriptNode *wnode, asCByteCode *bc) |
| 5760 | { |
| 5761 | // Add a variable scope that will be used by CompileBreak/Continue to know where to stop deallocating variables |
| 5762 | AddVariableScope(true, true); |
| 5763 | |
| 5764 | // We will use two labels for the while loop |
| 5765 | int beforeLabel = nextLabel++; |
| 5766 | int beforeTest = nextLabel++; |
| 5767 | int afterLabel = nextLabel++; |
| 5768 | |
| 5769 | continueLabels.PushLast(beforeTest); |
| 5770 | breakLabels.PushLast(afterLabel); |
| 5771 | |
| 5772 | // Add label before the statement |
| 5773 | bc->Label((short)beforeLabel); |
| 5774 | |
| 5775 | // Compile statement |
| 5776 | bool hasReturn; |
| 5777 | asCByteCode whileBC(engine); |
| 5778 | CompileStatement(wnode->firstChild, &hasReturn, &whileBC); |
| 5779 | |
| 5780 | // Add byte code for the statement |
| 5781 | LineInstr(bc, wnode->firstChild->tokenPos); |
| 5782 | bc->AddCode(&whileBC); |
| 5783 | |
| 5784 | // Add label before the expression |
| 5785 | bc->Label((short)beforeTest); |
| 5786 | |
| 5787 | // Add a suspend bytecode inside the loop to guarantee |
| 5788 | // that the application can suspend the execution |
| 5789 | bc->Instr(asBC_SUSPEND); |
| 5790 | bc->InstrPTR(asBC_JitEntry, 0); |
| 5791 | |
| 5792 | // Add a line instruction |
| 5793 | LineInstr(bc, wnode->lastChild->tokenPos); |
| 5794 | |
| 5795 | // Compile expression |
| 5796 | asCExprContext expr(engine); |
| 5797 | CompileAssignment(wnode->lastChild, &expr); |
| 5798 | |
| 5799 | if (ProcessPropertyGetAccessor(&expr, wnode) < 0) |
| 5800 | return; |
| 5801 | |
| 5802 | // If turned on, allow the compiler to use either 'bool opImplConv()' or 'bool opConv()' on the type |
| 5803 | if (engine->ep.boolConversionMode == 1) |
| 5804 | ImplicitConversion(&expr, asCDataType::CreatePrimitive(ttBool, false), wnode->lastChild, asIC_EXPLICIT_VAL_CAST); |
| 5805 | // else, allow value types to be converted to bool using 'bool opImplConv()' |
| 5806 | else if (expr.type.dataType.GetTypeInfo() && (expr.type.dataType.GetTypeInfo()->GetFlags() & asOBJ_VALUE)) |
| 5807 | ImplicitConversion(&expr, asCDataType::CreatePrimitive(ttBool, false), wnode->lastChild, asIC_IMPLICIT_CONV); |
| 5808 | |
| 5809 | if (!expr.type.dataType.IsEqualExceptRefAndConst(asCDataType::CreatePrimitive(ttBool, true))) |
| 5810 | { |
| 5811 | asCString str; |
| 5812 | str.Format(TXT_EXPR_MUST_BE_BOOL_s, expr.type.dataType.Format(outFunc->nameSpace).AddressOf()); |
| 5813 | Error(str, wnode->firstChild); |
| 5814 | } |
| 5815 | else |
| 5816 | { |
nothing calls this directly
no test coverage detected