| 1550 | } |
| 1551 | |
| 1552 | void GLSLCompiler::translateForStatement(glsl::astForStatement *statement) { |
| 1553 | m_breaks.push(std::vector<size_t>()); |
| 1554 | |
| 1555 | if (statement->init) { |
| 1556 | switch (statement->init->type) { |
| 1557 | case glsl::astStatement::kDeclaration: |
| 1558 | translateDeclarationStatement((glsl::astDeclarationStatement*)statement->init); |
| 1559 | break; |
| 1560 | case glsl::astStatement::kExpression: |
| 1561 | translateExpressionStatement((glsl::astExpressionStatement*)statement->init); |
| 1562 | break; |
| 1563 | } |
| 1564 | } |
| 1565 | int first_test = -1; |
| 1566 | int reg_test = -1; |
| 1567 | int rewind_adr = -1; |
| 1568 | |
| 1569 | if (statement->condition) { |
| 1570 | translateExpression(statement->condition); |
| 1571 | first_test = m_gen.Function.If(); |
| 1572 | } |
| 1573 | |
| 1574 | // on first iteration skip update() and regular condition() |
| 1575 | size_t body_start = m_gen.Function.Goto(); |
| 1576 | m_continueAddr.push(m_gen.Function.GetCurrentAddress()); |
| 1577 | |
| 1578 | m_exportLine(statement, true); |
| 1579 | |
| 1580 | // the third part of for loop |
| 1581 | if (statement->loop) |
| 1582 | translateExpression(statement->loop); |
| 1583 | |
| 1584 | if (statement->condition) { |
| 1585 | translateExpression(statement->condition); |
| 1586 | reg_test = m_gen.Function.If(); |
| 1587 | } |
| 1588 | |
| 1589 | m_gen.Function.SetAddress(body_start, m_gen.Function.GetCurrentAddress()); |
| 1590 | translateStatement(statement->body); |
| 1591 | |
| 1592 | // go to top (m_continueAddr == top) where top is where loop -> condition -> body starts |
| 1593 | size_t rewind_ref = m_gen.Function.Goto(); |
| 1594 | m_gen.Function.SetAddress(rewind_ref, m_continueAddr.top()); |
| 1595 | |
| 1596 | // address to which vm should go if condition is false |
| 1597 | if (reg_test != -1) |
| 1598 | m_gen.Function.SetAddress(reg_test, m_gen.Function.GetCurrentAddress()); |
| 1599 | if (first_test != -1) |
| 1600 | m_gen.Function.SetAddress(first_test, m_gen.Function.GetCurrentAddress()); |
| 1601 | |
| 1602 | for (size_t i = 0; i < m_breaks.top().size(); i++) |
| 1603 | m_gen.Function.SetAddress(m_breaks.top()[i], m_gen.Function.GetCurrentAddress()); |
| 1604 | |
| 1605 | m_continueAddr.pop(); |
| 1606 | m_breaks.pop(); |
| 1607 | } |
| 1608 | |
| 1609 | void GLSLCompiler::translateContinueStatement() { |