Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(19)

Side by Side Diff: src/sksl/SkSLIRGenerator.cpp

Issue 2427693002: more skslc hardening (Closed)
Patch Set: found another one Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/sksl/ir/SkSLTypeReference.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 auto var = std::unique_ptr<Variable>(new Variable(decl.fPosition, modifi ers, varDecl.fName, 197 auto var = std::unique_ptr<Variable>(new Variable(decl.fPosition, modifi ers, varDecl.fName,
198 *type, storage)); 198 *type, storage));
199 std::unique_ptr<Expression> value; 199 std::unique_ptr<Expression> value;
200 if (varDecl.fValue) { 200 if (varDecl.fValue) {
201 value = this->convertExpression(*varDecl.fValue); 201 value = this->convertExpression(*varDecl.fValue);
202 if (!value) { 202 if (!value) {
203 return nullptr; 203 return nullptr;
204 } 204 }
205 value = this->coerce(std::move(value), *type); 205 value = this->coerce(std::move(value), *type);
206 } 206 }
207 if ("sk_FragColor" == varDecl.fName && (*fSymbolTable)[varDecl.fName]) { 207 if (storage == Variable::kGlobal_Storage && "sk_FragColor" == varDecl.fN ame &&
208 (*fSymbolTable)[varDecl.fName]) {
208 // already defined, ignore 209 // already defined, ignore
209 } else if ((*fSymbolTable)[varDecl.fName] && 210 } else if (storage == Variable::kGlobal_Storage && (*fSymbolTable)[varDe cl.fName] &&
210 (*fSymbolTable)[varDecl.fName]->fKind == Symbol::kVariable_Ki nd && 211 (*fSymbolTable)[varDecl.fName]->fKind == Symbol::kVariable_Ki nd &&
211 ((Variable*) (*fSymbolTable)[varDecl.fName])->fModifiers.fLay out.fBuiltin >= 0) { 212 ((Variable*) (*fSymbolTable)[varDecl.fName])->fModifiers.fLay out.fBuiltin >= 0) {
212 // already defined, just update the modifiers 213 // already defined, just update the modifiers
213 Variable* old = (Variable*) (*fSymbolTable)[varDecl.fName]; 214 Variable* old = (Variable*) (*fSymbolTable)[varDecl.fName];
214 old->fModifiers = var->fModifiers; 215 old->fModifiers = var->fModifiers;
215 } else { 216 } else {
216 variables.emplace_back(var.get(), std::move(sizes), std::move(value) ); 217 variables.emplace_back(var.get(), std::move(sizes), std::move(value) );
217 fSymbolTable->add(varDecl.fName, std::move(var)); 218 fSymbolTable->add(varDecl.fName, std::move(var));
218 } 219 }
219 } 220 }
220 return std::unique_ptr<VarDeclarations>(new VarDeclarations(decl.fPosition, 221 return std::unique_ptr<VarDeclarations>(new VarDeclarations(decl.fPosition,
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 */ 684 */
684 static bool determine_binary_type(const Context& context, 685 static bool determine_binary_type(const Context& context,
685 Token::Kind op, 686 Token::Kind op,
686 const Type& left, 687 const Type& left,
687 const Type& right, 688 const Type& right,
688 const Type** outLeftType, 689 const Type** outLeftType,
689 const Type** outRightType, 690 const Type** outRightType,
690 const Type** outResultType, 691 const Type** outResultType,
691 bool tryFlipped) { 692 bool tryFlipped) {
692 bool isLogical; 693 bool isLogical;
694 bool validMatrixOrVectorOp;
693 switch (op) { 695 switch (op) {
696 case Token::EQ:
697 *outLeftType = &left;
698 *outRightType = &left;
699 *outResultType = &left;
700 return right.canCoerceTo(left);
694 case Token::EQEQ: // fall through 701 case Token::EQEQ: // fall through
695 case Token::NEQ: // fall through 702 case Token::NEQ:
703 isLogical = true;
704 validMatrixOrVectorOp = true;
705 break;
696 case Token::LT: // fall through 706 case Token::LT: // fall through
697 case Token::GT: // fall through 707 case Token::GT: // fall through
698 case Token::LTEQ: // fall through 708 case Token::LTEQ: // fall through
699 case Token::GTEQ: 709 case Token::GTEQ:
700 isLogical = true; 710 isLogical = true;
711 validMatrixOrVectorOp = false;
701 break; 712 break;
702 case Token::LOGICALOR: // fall through 713 case Token::LOGICALOR: // fall through
703 case Token::LOGICALAND: // fall through 714 case Token::LOGICALAND: // fall through
704 case Token::LOGICALXOR: // fall through 715 case Token::LOGICALXOR: // fall through
705 case Token::LOGICALOREQ: // fall through 716 case Token::LOGICALOREQ: // fall through
706 case Token::LOGICALANDEQ: // fall through 717 case Token::LOGICALANDEQ: // fall through
707 case Token::LOGICALXOREQ: 718 case Token::LOGICALXOREQ:
708 *outLeftType = context.fBool_Type.get(); 719 *outLeftType = context.fBool_Type.get();
709 *outRightType = context.fBool_Type.get(); 720 *outRightType = context.fBool_Type.get();
710 *outResultType = context.fBool_Type.get(); 721 *outResultType = context.fBool_Type.get();
(...skipping 30 matching lines...) Expand all
741 } else { 752 } else {
742 // result was a column vector, transpose it back to a ro w 753 // result was a column vector, transpose it back to a ro w
743 *outResultType = &(*outResultType)->toCompound(context, leftRows, 754 *outResultType = &(*outResultType)->toCompound(context, leftRows,
744 rightColu mns); 755 rightColu mns);
745 } 756 }
746 return leftColumns == rightRows; 757 return leftColumns == rightRows;
747 } else { 758 } else {
748 return false; 759 return false;
749 } 760 }
750 } 761 }
751 // fall through 762 isLogical = false;
763 validMatrixOrVectorOp = true;
764 break;
765 case Token::PLUS: // fall through
766 case Token::PLUSEQ: // fall through
767 case Token::MINUS: // fall through
768 case Token::MINUSEQ: // fall through
769 case Token::SLASH: // fall through
770 case Token::SLASHEQ:
771 isLogical = false;
772 validMatrixOrVectorOp = true;
773 break;
752 default: 774 default:
753 isLogical = false; 775 isLogical = false;
776 validMatrixOrVectorOp = false;
754 } 777 }
755 // FIXME: need to disallow illegal operations like vec3 > vec3. Also do not currently have 778 bool isVectorOrMatrix = left.kind() == Type::kVector_Kind || left.kind() == Type::kMatrix_Kind;
756 // full support for numbers other than float. 779 if (left.canCoerceTo(right) && (left.kind() == Type::kScalar_Kind ||
dogben 2016/10/17 15:30:36 I don't think this is correct for the FOOEQ cases.
757 if (left == right) { 780 (isVectorOrMatrix && validMatrixOrVectorOp))) {
758 *outLeftType = &left;
759 *outRightType = &left;
760 if (isLogical) {
761 *outResultType = context.fBool_Type.get();
762 } else {
763 *outResultType = &left;
764 }
765 return true;
766 }
767 // FIXME: incorrect for shift operations
dogben 2016/10/17 15:30:36 I think this still applies.
768 if (left.canCoerceTo(right)) {
769 *outLeftType = &right; 781 *outLeftType = &right;
770 *outRightType = &right; 782 *outRightType = &right;
771 if (isLogical) { 783 if (isLogical) {
772 *outResultType = context.fBool_Type.get(); 784 *outResultType = context.fBool_Type.get();
773 } else { 785 } else {
774 *outResultType = &right; 786 *outResultType = &right;
775 } 787 }
776 return true; 788 return true;
777 } 789 }
778 if ((left.kind() == Type::kVector_Kind || left.kind() == Type::kMatrix_Kind) && 790 if ((left.kind() == Type::kVector_Kind || left.kind() == Type::kMatrix_Kind) &&
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
828 case Token::BITWISEOREQ: // fall through 840 case Token::BITWISEOREQ: // fall through
829 case Token::BITWISEXOREQ: // fall through 841 case Token::BITWISEXOREQ: // fall through
830 case Token::BITWISEANDEQ: // fall through 842 case Token::BITWISEANDEQ: // fall through
831 case Token::LOGICALOREQ: // fall through 843 case Token::LOGICALOREQ: // fall through
832 case Token::LOGICALXOREQ: // fall through 844 case Token::LOGICALXOREQ: // fall through
833 case Token::LOGICALANDEQ: 845 case Token::LOGICALANDEQ:
834 this->markWrittenTo(*left); 846 this->markWrittenTo(*left);
835 default: 847 default:
836 break; 848 break;
837 } 849 }
850 left = this->coerce(std::move(left), *leftType);
851 right = this->coerce(std::move(right), *rightType);
852 if (!left || !right) {
853 return nullptr;
854 }
838 return std::unique_ptr<Expression>(new BinaryExpression(expression.fPosition , 855 return std::unique_ptr<Expression>(new BinaryExpression(expression.fPosition ,
839 this->coerce(std::mo ve(left), 856 std::move(left),
840 *leftTy pe),
841 expression.fOperator , 857 expression.fOperator ,
842 this->coerce(std::mo ve(right), 858 std::move(right),
843 *rightT ype),
844 *resultType)); 859 *resultType));
845 } 860 }
846 861
847 std::unique_ptr<Expression> IRGenerator::convertTernaryExpression( 862 std::unique_ptr<Expression> IRGenerator::convertTernaryExpression(
848 const ASTTernaryExpre ssion& expression) { 863 const ASTTernaryExpre ssion& expression) {
849 std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*exp ression.fTest), 864 std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*exp ression.fTest),
850 *fContext.fBool_Type); 865 *fContext.fBool_Type);
851 if (!test) { 866 if (!test) {
852 return nullptr; 867 return nullptr;
853 } 868 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
887 " argument"; 902 " argument";
888 if (function.fParameters.size() != 1) { 903 if (function.fParameters.size() != 1) {
889 msg += "s"; 904 msg += "s";
890 } 905 }
891 msg += ", but found " + to_string((uint64_t) arguments.size()); 906 msg += ", but found " + to_string((uint64_t) arguments.size());
892 fErrors.error(position, msg); 907 fErrors.error(position, msg);
893 return nullptr; 908 return nullptr;
894 } 909 }
895 for (size_t i = 0; i < arguments.size(); i++) { 910 for (size_t i = 0; i < arguments.size(); i++) {
896 arguments[i] = this->coerce(std::move(arguments[i]), function.fParameter s[i]->fType); 911 arguments[i] = this->coerce(std::move(arguments[i]), function.fParameter s[i]->fType);
912 if (!arguments[i]) {
913 return nullptr;
914 }
897 if (arguments[i] && (function.fParameters[i]->fModifiers.fFlags & Modifi ers::kOut_Flag)) { 915 if (arguments[i] && (function.fParameters[i]->fModifiers.fFlags & Modifi ers::kOut_Flag)) {
898 this->markWrittenTo(*arguments[i]); 916 this->markWrittenTo(*arguments[i]);
899 } 917 }
900 } 918 }
901 return std::unique_ptr<FunctionCall>(new FunctionCall(position, function, 919 return std::unique_ptr<FunctionCall>(new FunctionCall(position, function,
902 std::move(arguments))) ; 920 std::move(arguments))) ;
903 } 921 }
904 922
905 /** 923 /**
906 * Determines the cost of coercing the arguments of a function to the required t ypes. Returns true 924 * Determines the cost of coercing the arguments of a function to the required t ypes. Returns true
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
984 } 1002 }
985 if (args.size() == 1 && args[0]->fType == type) { 1003 if (args.size() == 1 && args[0]->fType == type) {
986 // argument is already the right type, just return it 1004 // argument is already the right type, just return it
987 return std::move(args[0]); 1005 return std::move(args[0]);
988 } 1006 }
989 if (type.isNumber()) { 1007 if (type.isNumber()) {
990 if (args.size() != 1) { 1008 if (args.size() != 1) {
991 fErrors.error(position, "invalid arguments to '" + type.description( ) + 1009 fErrors.error(position, "invalid arguments to '" + type.description( ) +
992 "' constructor, (expected exactly 1 argument , but found " + 1010 "' constructor, (expected exactly 1 argument , but found " +
993 to_string((uint64_t) args.size()) + ")"); 1011 to_string((uint64_t) args.size()) + ")");
1012 return nullptr;
994 } 1013 }
995 if (args[0]->fType == *fContext.fBool_Type) { 1014 if (args[0]->fType == *fContext.fBool_Type) {
996 std::unique_ptr<IntLiteral> zero(new IntLiteral(fContext, position, 0)); 1015 std::unique_ptr<IntLiteral> zero(new IntLiteral(fContext, position, 0));
997 std::unique_ptr<IntLiteral> one(new IntLiteral(fContext, position, 1 )); 1016 std::unique_ptr<IntLiteral> one(new IntLiteral(fContext, position, 1 ));
998 return std::unique_ptr<Expression>( 1017 return std::unique_ptr<Expression>(
999 new TernaryExpression(position, std::mo ve(args[0]), 1018 new TernaryExpression(position, std::mo ve(args[0]),
1000 this->coerce(std: :move(one), type), 1019 this->coerce(std: :move(one), type),
1001 this->coerce(std: :move(zero), 1020 this->coerce(std: :move(zero),
1002 type ))); 1021 type )));
1003 } else if (!args[0]->fType.isNumber()) { 1022 } else if (!args[0]->fType.isNumber()) {
1004 fErrors.error(position, "invalid argument to '" + type.description() + 1023 fErrors.error(position, "invalid argument to '" + type.description() +
1005 "' constructor (expected a number or bool, b ut found '" + 1024 "' constructor (expected a number or bool, b ut found '" +
1006 args[0]->fType.description() + "')"); 1025 args[0]->fType.description() + "')");
1007 } 1026 }
1008 if (args[0]->fKind == Expression::kIntLiteral_Kind && (type == *fContext .fInt_Type || 1027 if (args[0]->fKind == Expression::kIntLiteral_Kind && (type == *fContext .fInt_Type ||
1009 type == *fContext.fUInt_Type)) { 1028 type == *fContext.fUInt_Type)) {
1010 return std::unique_ptr<Expression>(new IntLiteral(fContext, 1029 return std::unique_ptr<Expression>(new IntLiteral(fContext,
1011 position, 1030 position,
1012 ((IntLiteral&) *ar gs[0]).fValue, 1031 ((IntLiteral&) *ar gs[0]).fValue,
1013 &type)); 1032 &type));
1014 } 1033 }
1015 } else if (kind == Type::kArray_Kind) { 1034 } else if (kind == Type::kArray_Kind) {
1016 const Type& base = type.componentType(); 1035 const Type& base = type.componentType();
1017 for (size_t i = 0; i < args.size(); i++) { 1036 for (size_t i = 0; i < args.size(); i++) {
1018 args[i] = this->coerce(std::move(args[i]), base); 1037 args[i] = this->coerce(std::move(args[i]), base);
1038 if (!args[i]) {
1039 return nullptr;
1040 }
1019 } 1041 }
1020 } else { 1042 } else {
1021 ASSERT(kind == Type::kVector_Kind || kind == Type::kMatrix_Kind); 1043 ASSERT(kind == Type::kVector_Kind || kind == Type::kMatrix_Kind);
1022 int actual = 0; 1044 int actual = 0;
1023 for (size_t i = 0; i < args.size(); i++) { 1045 for (size_t i = 0; i < args.size(); i++) {
1024 if (args[i]->fType.kind() == Type::kVector_Kind || 1046 if (args[i]->fType.kind() == Type::kVector_Kind ||
1025 args[i]->fType.kind() == Type::kMatrix_Kind) { 1047 args[i]->fType.kind() == Type::kMatrix_Kind) {
1026 int columns = args[i]->fType.columns(); 1048 int columns = args[i]->fType.columns();
1027 int rows = args[i]->fType.rows(); 1049 int rows = args[i]->fType.rows();
1028 args[i] = this->coerce(std::move(args[i]), 1050 args[i] = this->coerce(std::move(args[i]),
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
1292 1314
1293 void IRGenerator::checkValid(const Expression& expr) { 1315 void IRGenerator::checkValid(const Expression& expr) {
1294 switch (expr.fKind) { 1316 switch (expr.fKind) {
1295 case Expression::kFunctionReference_Kind: 1317 case Expression::kFunctionReference_Kind:
1296 fErrors.error(expr.fPosition, "expected '(' to begin function call") ; 1318 fErrors.error(expr.fPosition, "expected '(' to begin function call") ;
1297 break; 1319 break;
1298 case Expression::kTypeReference_Kind: 1320 case Expression::kTypeReference_Kind:
1299 fErrors.error(expr.fPosition, "expected '(' to begin constructor inv ocation"); 1321 fErrors.error(expr.fPosition, "expected '(' to begin constructor inv ocation");
1300 break; 1322 break;
1301 default: 1323 default:
1302 ASSERT(expr.fType != *fContext.fInvalid_Type); 1324 if (expr.fType == *fContext.fInvalid_Type) {
1303 break; 1325 fErrors.error(expr.fPosition, "invalid expression");
1326 }
1304 } 1327 }
1305 } 1328 }
1306 1329
1307 void IRGenerator::markReadFrom(const Variable& var) { 1330 void IRGenerator::markReadFrom(const Variable& var) {
1308 var.fIsReadFrom = true; 1331 var.fIsReadFrom = true;
1309 } 1332 }
1310 1333
1311 static bool has_duplicates(const Swizzle& swizzle) { 1334 static bool has_duplicates(const Swizzle& swizzle) {
1312 int bits = 0; 1335 int bits = 0;
1313 for (int idx : swizzle.fComponents) { 1336 for (int idx : swizzle.fComponents) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1345 case Expression::kIndex_Kind: 1368 case Expression::kIndex_Kind:
1346 this->markWrittenTo(*((IndexExpression&) expr).fBase); 1369 this->markWrittenTo(*((IndexExpression&) expr).fBase);
1347 break; 1370 break;
1348 default: 1371 default:
1349 fErrors.error(expr.fPosition, "cannot assign to '" + expr.descriptio n() + "'"); 1372 fErrors.error(expr.fPosition, "cannot assign to '" + expr.descriptio n() + "'");
1350 break; 1373 break;
1351 } 1374 }
1352 } 1375 }
1353 1376
1354 } 1377 }
OLDNEW
« no previous file with comments | « no previous file | src/sksl/ir/SkSLTypeReference.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698