39#include <forward_list>
49 struct AppendRTAdjustFixupHelper :
public IRHelpers {
52 , fRTAdjust(rtAdjust) {
57 std::unique_ptr<Expression> Pos()
const {
58 return Field(&fSkPositionField->owner(), fSkPositionField->fieldIndex());
61 std::unique_ptr<Expression> Adjust()
const {
65 std::unique_ptr<Statement> makeFixupStmt()
const {
83 AppendRTAdjustFixupHelper helper(context, rtAdjust);
91 std::unique_ptr<Statement> body,
100 this->addLocalVariable(var,
pos);
104 ~Finalizer()
override {
106 SkASSERT(fContinuableLevel == std::forward_list<int>{0});
111 fContext.fErrors->error(
pos,
"unsized arrays are not permitted here");
118 size_t prevSlotsUsed = fSlotsUsed;
124 "' exceeds the stack size limit");
128 void fuseVariableDeclarationsWithInitialization(std::unique_ptr<Statement>& stmt) {
129 switch (stmt->kind()) {
131 case Statement::Kind::kBlock:
137 case Statement::Kind::kVarDeclaration:
140 fUninitializedVarDecl = &decl;
148 fUninitializedVarDecl =
nullptr;
151 case Statement::Kind::kExpression: {
154 if (fUninitializedVarDecl) {
156 fUninitializedVarDecl =
nullptr;
186 vardecl->
value() = std::move(binaryExpr.
right());
196 bool functionReturnsValue()
const {
197 return !fFunction.returnType().isVoid();
200 bool visitExpressionPtr(std::unique_ptr<Expression>& expr)
override {
205 bool visitStatementPtr(std::unique_ptr<Statement>& stmt)
override {
209 if (
fContext.fConfig->fSettings.fOptimize) {
210 this->fuseVariableDeclarationsWithInitialization(stmt);
214 switch (stmt->kind()) {
215 case Statement::Kind::kVarDeclaration:
219 case Statement::Kind::kReturn: {
226 "early returns from vertex programs are not supported");
232 if (this->functionReturnsValue()) {
234 returnStmt.
setExpression(fFunction.returnType().coerceExpression(
239 "may not return a value from a void function");
243 if (this->functionReturnsValue()) {
246 "expected function to return '" +
247 fFunction.returnType().displayName() +
"'");
252 case Statement::Kind::kDo:
253 case Statement::Kind::kFor: {
255 ++fContinuableLevel.front();
256 bool result = INHERITED::visitStatementPtr(stmt);
257 --fContinuableLevel.front();
261 case Statement::Kind::kSwitch: {
263 fContinuableLevel.push_front(0);
264 bool result = INHERITED::visitStatementPtr(stmt);
265 fContinuableLevel.pop_front();
269 case Statement::Kind::kBreak:
270 if (fBreakableLevel == 0) {
271 fContext.fErrors->error(stmt->fPosition,
272 "break statement must be inside a loop or switch");
277 if (fContinuableLevel.front() == 0) {
278 if (std::any_of(fContinuableLevel.begin(),
279 fContinuableLevel.end(),
280 [](
int level) { return level > 0; })) {
281 fContext.fErrors->error(stmt->fPosition,
282 "continue statement cannot be used in a switch");
284 fContext.fErrors->error(stmt->fPosition,
285 "continue statement must be inside a loop");
293 return INHERITED::visitStatementPtr(stmt);
300 int fBreakableLevel = 0;
302 size_t fSlotsUsed = 0;
305 std::forward_list<int> fContinuableLevel{0};
318 "' should not have a definition");
326 "' must be a braced block");
333 "' was already defined");
346 "' can exit without returning a value");
355 std::unique_ptr<Statement> body,
361 return std::make_unique<FunctionDefinition>(
pos, &
function, builtin, std::move(
body));
std::unique_ptr< Expression > & left()
std::unique_ptr< Expression > & right()
Operator getOperator() const
const StatementArray & children() const
static constexpr const char RTADJUST_NAME[]
static constexpr const char POSITION_NAME[]
SymbolTable * fSymbolTable
void error(Position position, std::string_view msg)
std::unique_ptr< Statement > & body()
static std::unique_ptr< FunctionDefinition > Make(const Context &context, Position pos, const FunctionDeclaration &function, std::unique_ptr< Statement > body, bool builtin)
static std::unique_ptr< FunctionDefinition > Convert(const Context &context, Position pos, const FunctionDeclaration &function, std::unique_ptr< Statement > body, bool builtin)
static std::unique_ptr< Statement > Make()
void setExpression(std::unique_ptr< Expression > expr)
std::unique_ptr< Expression > & expression()
const Symbol * find(std::string_view name) const
std::string_view name() const
const Type & type() const
virtual size_t slotCount() const
virtual bool isOrContainsUnsizedArray() const
std::unique_ptr< Expression > & value()
const Variable * variable() const
static size_t Add(size_t x, size_t y)
Dart_NativeFunction function
bool ContainsVariable(const Expression &expr, const Variable &var)
bool CanExitWithoutReturningValue(const FunctionDeclaration &funcDecl, const Statement &body)
static constexpr int kVariableSlotLimit
static void append_rtadjust_fixup_to_vertex_main(const Context &context, const FunctionDeclaration &decl, Block &body)
static void Finalizer(void *isolate_callback_data, void *buffer)
static bool IsVertex(ProgramKind kind)