| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * Copyright 2016 Google Inc. | 2  * Copyright 2016 Google Inc. | 
| 3  * | 3  * | 
| 4  * Use of this source code is governed by a BSD-style license that can be | 4  * Use of this source code is governed by a BSD-style license that can be | 
| 5  * found in the LICENSE file. | 5  * found in the LICENSE file. | 
| 6  */ | 6  */ | 
| 7 | 7 | 
| 8 #include "SkSLIRGenerator.h" | 8 #include "SkSLIRGenerator.h" | 
| 9 | 9 | 
| 10 #include "limits.h" | 10 #include "limits.h" | 
| (...skipping 24 matching lines...) Expand all  Loading... | 
| 35 #include "ir/SkSLInterfaceBlock.h" | 35 #include "ir/SkSLInterfaceBlock.h" | 
| 36 #include "ir/SkSLIntLiteral.h" | 36 #include "ir/SkSLIntLiteral.h" | 
| 37 #include "ir/SkSLLayout.h" | 37 #include "ir/SkSLLayout.h" | 
| 38 #include "ir/SkSLPostfixExpression.h" | 38 #include "ir/SkSLPostfixExpression.h" | 
| 39 #include "ir/SkSLPrefixExpression.h" | 39 #include "ir/SkSLPrefixExpression.h" | 
| 40 #include "ir/SkSLReturnStatement.h" | 40 #include "ir/SkSLReturnStatement.h" | 
| 41 #include "ir/SkSLSwizzle.h" | 41 #include "ir/SkSLSwizzle.h" | 
| 42 #include "ir/SkSLTernaryExpression.h" | 42 #include "ir/SkSLTernaryExpression.h" | 
| 43 #include "ir/SkSLUnresolvedFunction.h" | 43 #include "ir/SkSLUnresolvedFunction.h" | 
| 44 #include "ir/SkSLVariable.h" | 44 #include "ir/SkSLVariable.h" | 
| 45 #include "ir/SkSLVarDeclaration.h" | 45 #include "ir/SkSLVarDeclarations.h" | 
| 46 #include "ir/SkSLVarDeclarationStatement.h" | 46 #include "ir/SkSLVarDeclarationsStatement.h" | 
| 47 #include "ir/SkSLVariableReference.h" | 47 #include "ir/SkSLVariableReference.h" | 
| 48 #include "ir/SkSLWhileStatement.h" | 48 #include "ir/SkSLWhileStatement.h" | 
| 49 | 49 | 
| 50 namespace SkSL { | 50 namespace SkSL { | 
| 51 | 51 | 
| 52 class AutoSymbolTable { | 52 class AutoSymbolTable { | 
| 53 public: | 53 public: | 
| 54     AutoSymbolTable(IRGenerator* ir) | 54     AutoSymbolTable(IRGenerator* ir) | 
| 55     : fIR(ir) | 55     : fIR(ir) | 
| 56     , fPrevious(fIR->fSymbolTable) { | 56     , fPrevious(fIR->fSymbolTable) { | 
| 57         fIR->pushSymbolTable(); | 57         fIR->pushSymbolTable(); | 
| 58     } | 58     } | 
| 59 | 59 | 
| 60     ~AutoSymbolTable() { | 60     ~AutoSymbolTable() { | 
| 61         fIR->popSymbolTable(); | 61         fIR->popSymbolTable(); | 
| 62         ASSERT(fPrevious == fIR->fSymbolTable); | 62         ASSERT(fPrevious == fIR->fSymbolTable); | 
| 63     } | 63     } | 
| 64 | 64 | 
| 65     IRGenerator* fIR; | 65     IRGenerator* fIR; | 
| 66     std::shared_ptr<SymbolTable> fPrevious; | 66     std::shared_ptr<SymbolTable> fPrevious; | 
| 67 }; | 67 }; | 
| 68 | 68 | 
|  | 69 class AutoLoopLevel { | 
|  | 70 public: | 
|  | 71     AutoLoopLevel(IRGenerator* ir) | 
|  | 72     : fIR(ir) { | 
|  | 73         fIR->fLoopLevel++; | 
|  | 74     } | 
|  | 75 | 
|  | 76     ~AutoLoopLevel() { | 
|  | 77         fIR->fLoopLevel--; | 
|  | 78     } | 
|  | 79 | 
|  | 80     IRGenerator* fIR; | 
|  | 81 }; | 
|  | 82 | 
| 69 IRGenerator::IRGenerator(const Context* context, std::shared_ptr<SymbolTable> sy
      mbolTable, | 83 IRGenerator::IRGenerator(const Context* context, std::shared_ptr<SymbolTable> sy
      mbolTable, | 
| 70                          ErrorReporter& errorReporter) | 84                          ErrorReporter& errorReporter) | 
| 71 : fContext(*context) | 85 : fContext(*context) | 
| 72 , fCurrentFunction(nullptr) | 86 , fCurrentFunction(nullptr) | 
| 73 , fSymbolTable(std::move(symbolTable)) | 87 , fSymbolTable(std::move(symbolTable)) | 
|  | 88 , fLoopLevel(0) | 
| 74 , fErrors(errorReporter) {} | 89 , fErrors(errorReporter) {} | 
| 75 | 90 | 
| 76 void IRGenerator::pushSymbolTable() { | 91 void IRGenerator::pushSymbolTable() { | 
| 77     fSymbolTable.reset(new SymbolTable(std::move(fSymbolTable), fErrors)); | 92     fSymbolTable.reset(new SymbolTable(std::move(fSymbolTable), fErrors)); | 
| 78 } | 93 } | 
| 79 | 94 | 
| 80 void IRGenerator::popSymbolTable() { | 95 void IRGenerator::popSymbolTable() { | 
| 81     fSymbolTable = fSymbolTable->fParent; | 96     fSymbolTable = fSymbolTable->fParent; | 
| 82 } | 97 } | 
| 83 | 98 | 
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 228         ifFalse = this->convertStatement(*s.fIfFalse); | 243         ifFalse = this->convertStatement(*s.fIfFalse); | 
| 229         if (!ifFalse) { | 244         if (!ifFalse) { | 
| 230             return nullptr; | 245             return nullptr; | 
| 231         } | 246         } | 
| 232     } | 247     } | 
| 233     return std::unique_ptr<Statement>(new IfStatement(s.fPosition, std::move(tes
      t), | 248     return std::unique_ptr<Statement>(new IfStatement(s.fPosition, std::move(tes
      t), | 
| 234                                                       std::move(ifTrue), std::mo
      ve(ifFalse))); | 249                                                       std::move(ifTrue), std::mo
      ve(ifFalse))); | 
| 235 } | 250 } | 
| 236 | 251 | 
| 237 std::unique_ptr<Statement> IRGenerator::convertFor(const ASTForStatement& f) { | 252 std::unique_ptr<Statement> IRGenerator::convertFor(const ASTForStatement& f) { | 
|  | 253     AutoLoopLevel level(this); | 
| 238     AutoSymbolTable table(this); | 254     AutoSymbolTable table(this); | 
| 239     std::unique_ptr<Statement> initializer = this->convertStatement(*f.fInitiali
      zer); | 255     std::unique_ptr<Statement> initializer; | 
| 240     if (!initializer) { | 256     if (f.fInitializer) { | 
| 241         return nullptr; | 257         initializer = this->convertStatement(*f.fInitializer); | 
|  | 258         if (!initializer) { | 
|  | 259             return nullptr; | 
|  | 260         } | 
| 242     } | 261     } | 
| 243     std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*f.f
      Test), | 262     std::unique_ptr<Expression> test; | 
| 244                                                     *fContext.fBool_Type); | 263     if (f.fTest) { | 
| 245     if (!test) { | 264         test = this->coerce(this->convertExpression(*f.fTest), *fContext.fBool_T
      ype); | 
| 246         return nullptr; | 265         if (!test) { | 
|  | 266             return nullptr; | 
|  | 267         } | 
| 247     } | 268     } | 
| 248     std::unique_ptr<Expression> next = this->convertExpression(*f.fNext); | 269     std::unique_ptr<Expression> next; | 
| 249     if (!next) { | 270     if (f.fNext) { | 
| 250         return nullptr; | 271         next = this->convertExpression(*f.fNext); | 
|  | 272         if (!next) { | 
|  | 273             return nullptr; | 
|  | 274         } | 
|  | 275         this->checkValid(*next); | 
| 251     } | 276     } | 
| 252     this->checkValid(*next); |  | 
| 253     std::unique_ptr<Statement> statement = this->convertStatement(*f.fStatement)
      ; | 277     std::unique_ptr<Statement> statement = this->convertStatement(*f.fStatement)
      ; | 
| 254     if (!statement) { | 278     if (!statement) { | 
| 255         return nullptr; | 279         return nullptr; | 
| 256     } | 280     } | 
| 257     return std::unique_ptr<Statement>(new ForStatement(f.fPosition, std::move(in
      itializer), | 281     return std::unique_ptr<Statement>(new ForStatement(f.fPosition, std::move(in
      itializer), | 
| 258                                                        std::move(test), std::mov
      e(next), | 282                                                        std::move(test), std::mov
      e(next), | 
| 259                                                        std::move(statement), fSy
      mbolTable)); | 283                                                        std::move(statement), fSy
      mbolTable)); | 
| 260 } | 284 } | 
| 261 | 285 | 
| 262 std::unique_ptr<Statement> IRGenerator::convertWhile(const ASTWhileStatement& w)
       { | 286 std::unique_ptr<Statement> IRGenerator::convertWhile(const ASTWhileStatement& w)
       { | 
|  | 287     AutoLoopLevel level(this); | 
| 263     std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*w.f
      Test), | 288     std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*w.f
      Test), | 
| 264                                                     *fContext.fBool_Type); | 289                                                     *fContext.fBool_Type); | 
| 265     if (!test) { | 290     if (!test) { | 
| 266         return nullptr; | 291         return nullptr; | 
| 267     } | 292     } | 
| 268     std::unique_ptr<Statement> statement = this->convertStatement(*w.fStatement)
      ; | 293     std::unique_ptr<Statement> statement = this->convertStatement(*w.fStatement)
      ; | 
| 269     if (!statement) { | 294     if (!statement) { | 
| 270         return nullptr; | 295         return nullptr; | 
| 271     } | 296     } | 
| 272     return std::unique_ptr<Statement>(new WhileStatement(w.fPosition, std::move(
      test), | 297     return std::unique_ptr<Statement>(new WhileStatement(w.fPosition, std::move(
      test), | 
| 273                                                          std::move(statement))); | 298                                                          std::move(statement))); | 
| 274 } | 299 } | 
| 275 | 300 | 
| 276 std::unique_ptr<Statement> IRGenerator::convertDo(const ASTDoStatement& d) { | 301 std::unique_ptr<Statement> IRGenerator::convertDo(const ASTDoStatement& d) { | 
|  | 302     AutoLoopLevel level(this); | 
| 277     std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*d.f
      Test), | 303     std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*d.f
      Test), | 
| 278                                                     *fContext.fBool_Type); | 304                                                     *fContext.fBool_Type); | 
| 279     if (!test) { | 305     if (!test) { | 
| 280         return nullptr; | 306         return nullptr; | 
| 281     } | 307     } | 
| 282     std::unique_ptr<Statement> statement = this->convertStatement(*d.fStatement)
      ; | 308     std::unique_ptr<Statement> statement = this->convertStatement(*d.fStatement)
      ; | 
| 283     if (!statement) { | 309     if (!statement) { | 
| 284         return nullptr; | 310         return nullptr; | 
| 285     } | 311     } | 
| 286     return std::unique_ptr<Statement>(new DoStatement(d.fPosition, std::move(sta
      tement), | 312     return std::unique_ptr<Statement>(new DoStatement(d.fPosition, std::move(sta
      tement), | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
| 316     } else { | 342     } else { | 
| 317         if (fCurrentFunction->fReturnType != *fContext.fVoid_Type) { | 343         if (fCurrentFunction->fReturnType != *fContext.fVoid_Type) { | 
| 318             fErrors.error(r.fPosition, "expected function to return '" + | 344             fErrors.error(r.fPosition, "expected function to return '" + | 
| 319                                        fCurrentFunction->fReturnType.description
      () + "'"); | 345                                        fCurrentFunction->fReturnType.description
      () + "'"); | 
| 320         } | 346         } | 
| 321         return std::unique_ptr<Statement>(new ReturnStatement(r.fPosition)); | 347         return std::unique_ptr<Statement>(new ReturnStatement(r.fPosition)); | 
| 322     } | 348     } | 
| 323 } | 349 } | 
| 324 | 350 | 
| 325 std::unique_ptr<Statement> IRGenerator::convertBreak(const ASTBreakStatement& b)
       { | 351 std::unique_ptr<Statement> IRGenerator::convertBreak(const ASTBreakStatement& b)
       { | 
| 326     return std::unique_ptr<Statement>(new BreakStatement(b.fPosition)); | 352     if (fLoopLevel > 0) { | 
|  | 353         return std::unique_ptr<Statement>(new BreakStatement(b.fPosition)); | 
|  | 354     } else { | 
|  | 355         fErrors.error(b.fPosition, "break statement must be inside a loop"); | 
|  | 356         return nullptr; | 
|  | 357     } | 
| 327 } | 358 } | 
| 328 | 359 | 
| 329 std::unique_ptr<Statement> IRGenerator::convertContinue(const ASTContinueStateme
      nt& c) { | 360 std::unique_ptr<Statement> IRGenerator::convertContinue(const ASTContinueStateme
      nt& c) { | 
| 330     return std::unique_ptr<Statement>(new ContinueStatement(c.fPosition)); | 361     if (fLoopLevel > 0) { | 
|  | 362         return std::unique_ptr<Statement>(new ContinueStatement(c.fPosition)); | 
|  | 363     } else { | 
|  | 364         fErrors.error(c.fPosition, "continue statement must be inside a loop"); | 
|  | 365         return nullptr; | 
|  | 366     } | 
| 331 } | 367 } | 
| 332 | 368 | 
| 333 std::unique_ptr<Statement> IRGenerator::convertDiscard(const ASTDiscardStatement
      & d) { | 369 std::unique_ptr<Statement> IRGenerator::convertDiscard(const ASTDiscardStatement
      & d) { | 
| 334     return std::unique_ptr<Statement>(new DiscardStatement(d.fPosition)); | 370     return std::unique_ptr<Statement>(new DiscardStatement(d.fPosition)); | 
| 335 } | 371 } | 
| 336 | 372 | 
| 337 static const Type& expand_generics(const Type& type, int i) { | 373 static const Type& expand_generics(const Type& type, int i) { | 
| 338     if (type.kind() == Type::kGeneric_Kind) { | 374     if (type.kind() == Type::kGeneric_Kind) { | 
| 339         return *type.coercibleTypes()[i]; | 375         return *type.coercibleTypes()[i]; | 
| 340     } | 376     } | 
| (...skipping 958 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1299         case Expression::kIndex_Kind: | 1335         case Expression::kIndex_Kind: | 
| 1300             this->markWrittenTo(*((IndexExpression&) expr).fBase); | 1336             this->markWrittenTo(*((IndexExpression&) expr).fBase); | 
| 1301             break; | 1337             break; | 
| 1302         default: | 1338         default: | 
| 1303             fErrors.error(expr.fPosition, "cannot assign to '" + expr.descriptio
      n() + "'"); | 1339             fErrors.error(expr.fPosition, "cannot assign to '" + expr.descriptio
      n() + "'"); | 
| 1304             break; | 1340             break; | 
| 1305     } | 1341     } | 
| 1306 } | 1342 } | 
| 1307 | 1343 | 
| 1308 } | 1344 } | 
| OLD | NEW | 
|---|