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 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 auto var = std::unique_ptr<Variable>(new Variable(decl.fPosition, modifi
ers, varDecl.fName, | 182 auto var = std::unique_ptr<Variable>(new Variable(decl.fPosition, modifi
ers, varDecl.fName, |
183 *type, storage)); | 183 *type, storage)); |
184 std::unique_ptr<Expression> value; | 184 std::unique_ptr<Expression> value; |
185 if (varDecl.fValue) { | 185 if (varDecl.fValue) { |
186 value = this->convertExpression(*varDecl.fValue); | 186 value = this->convertExpression(*varDecl.fValue); |
187 if (!value) { | 187 if (!value) { |
188 return nullptr; | 188 return nullptr; |
189 } | 189 } |
190 value = this->coerce(std::move(value), *type); | 190 value = this->coerce(std::move(value), *type); |
191 } | 191 } |
192 if ("sk_FragColor" == varDecl.fName && (*fSymbolTable)[varDecl.fName]) { | 192 if ("gl_FragCoord" == varDecl.fName && (*fSymbolTable)[varDecl.fName]) { |
193 // already defined, ignore | |
194 } else if ((*fSymbolTable)[varDecl.fName] && | |
195 (*fSymbolTable)[varDecl.fName]->fKind == Symbol::kVariable_Ki
nd && | |
196 ((Variable*) (*fSymbolTable)[varDecl.fName])->fModifiers.fLay
out.fBuiltin >= 0) { | |
197 // already defined, just update the modifiers | 193 // already defined, just update the modifiers |
198 Variable* old = (Variable*) (*fSymbolTable)[varDecl.fName]; | 194 Variable* old = (Variable*) (*fSymbolTable)[varDecl.fName]; |
199 int builtin = old->fModifiers.fLayout.fBuiltin; | |
200 old->fModifiers = var->fModifiers; | 195 old->fModifiers = var->fModifiers; |
201 old->fModifiers.fLayout.fBuiltin = builtin; | |
202 } else { | 196 } else { |
203 variables.emplace_back(var.get(), std::move(sizes), std::move(value)
); | 197 variables.emplace_back(var.get(), std::move(sizes), std::move(value)
); |
204 fSymbolTable->add(varDecl.fName, std::move(var)); | 198 fSymbolTable->add(varDecl.fName, std::move(var)); |
205 } | 199 } |
206 } | 200 } |
207 return std::unique_ptr<VarDeclarations>(new VarDeclarations(decl.fPosition, | 201 return std::unique_ptr<VarDeclarations>(new VarDeclarations(decl.fPosition, |
208 baseType, | 202 baseType, |
209 std::move(variab
les))); | 203 std::move(variab
les))); |
210 } | 204 } |
211 | 205 |
212 std::unique_ptr<ModifiersDeclaration> IRGenerator::convertModifiersDeclaration( | |
213 const ASTModifi
ersDeclaration& m) { | |
214 Modifiers modifiers = this->convertModifiers(m.fModifiers); | |
215 return std::unique_ptr<ModifiersDeclaration>(new ModifiersDeclaration(modifi
ers)); | |
216 } | |
217 | |
218 std::unique_ptr<Statement> IRGenerator::convertIf(const ASTIfStatement& s) { | 206 std::unique_ptr<Statement> IRGenerator::convertIf(const ASTIfStatement& s) { |
219 std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*s.f
Test), | 207 std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*s.f
Test), |
220 *fContext.fBool_Type); | 208 *fContext.fBool_Type); |
221 if (!test) { | 209 if (!test) { |
222 return nullptr; | 210 return nullptr; |
223 } | 211 } |
224 std::unique_ptr<Statement> ifTrue = this->convertStatement(*s.fIfTrue); | 212 std::unique_ptr<Statement> ifTrue = this->convertStatement(*s.fIfTrue); |
225 if (!ifTrue) { | 213 if (!ifTrue) { |
226 return nullptr; | 214 return nullptr; |
227 } | 215 } |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
424 FunctionDeclaration newDecl(f.fPosition, f.fName, parame
ters, *returnType); | 412 FunctionDeclaration newDecl(f.fPosition, f.fName, parame
ters, *returnType); |
425 fErrors.error(f.fPosition, "functions '" + newDecl.descr
iption() + | 413 fErrors.error(f.fPosition, "functions '" + newDecl.descr
iption() + |
426 "' and '" + other->descriptio
n() + | 414 "' and '" + other->descriptio
n() + |
427 "' differ only in return type
"); | 415 "' differ only in return type
"); |
428 return nullptr; | 416 return nullptr; |
429 } | 417 } |
430 decl = other; | 418 decl = other; |
431 for (size_t i = 0; i < parameters.size(); i++) { | 419 for (size_t i = 0; i < parameters.size(); i++) { |
432 if (parameters[i]->fModifiers != other->fParameters[i]->
fModifiers) { | 420 if (parameters[i]->fModifiers != other->fParameters[i]->
fModifiers) { |
433 fErrors.error(f.fPosition, "modifiers on parameter "
+ | 421 fErrors.error(f.fPosition, "modifiers on parameter "
+ |
434 to_string((uint64_t) i +
1) + | 422 to_string(i + 1) + " diff
er between " + |
435 " differ between declarat
ion and " | 423 "declaration and definiti
on"); |
436 "definition"); | |
437 return nullptr; | 424 return nullptr; |
438 } | 425 } |
439 } | 426 } |
440 if (other->fDefined) { | 427 if (other->fDefined) { |
441 fErrors.error(f.fPosition, "duplicate definition of " + | 428 fErrors.error(f.fPosition, "duplicate definition of " + |
442 other->description()); | 429 other->description()); |
443 } | 430 } |
444 break; | 431 break; |
445 } | 432 } |
446 } | 433 } |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
622 return nullptr; | 609 return nullptr; |
623 } | 610 } |
624 if (type.kind() == Type::kScalar_Kind) { | 611 if (type.kind() == Type::kScalar_Kind) { |
625 std::vector<std::unique_ptr<Expression>> args; | 612 std::vector<std::unique_ptr<Expression>> args; |
626 args.push_back(std::move(expr)); | 613 args.push_back(std::move(expr)); |
627 ASTIdentifier id(Position(), type.description()); | 614 ASTIdentifier id(Position(), type.description()); |
628 std::unique_ptr<Expression> ctor = this->convertIdentifier(id); | 615 std::unique_ptr<Expression> ctor = this->convertIdentifier(id); |
629 ASSERT(ctor); | 616 ASSERT(ctor); |
630 return this->call(Position(), std::move(ctor), std::move(args)); | 617 return this->call(Position(), std::move(ctor), std::move(args)); |
631 } | 618 } |
632 std::vector<std::unique_ptr<Expression>> args; | 619 ABORT("cannot coerce %s to %s", expr->fType.description().c_str(), |
633 args.push_back(std::move(expr)); | 620 type.description().c_str()); |
634 return std::unique_ptr<Expression>(new Constructor(Position(), type, std::mo
ve(args))); | |
635 } | 621 } |
636 | 622 |
637 static bool is_matrix_multiply(const Type& left, const Type& right) { | 623 static bool is_matrix_multiply(const Type& left, const Type& right) { |
638 if (left.kind() == Type::kMatrix_Kind) { | 624 if (left.kind() == Type::kMatrix_Kind) { |
639 return right.kind() == Type::kMatrix_Kind || right.kind() == Type::kVect
or_Kind; | 625 return right.kind() == Type::kMatrix_Kind || right.kind() == Type::kVect
or_Kind; |
640 } | 626 } |
641 return left.kind() == Type::kVector_Kind && right.kind() == Type::kMatrix_Ki
nd; | 627 return left.kind() == Type::kVector_Kind && right.kind() == Type::kMatrix_Ki
nd; |
642 } | 628 } |
643 /** | 629 /** |
644 * Determines the operand and result types of a binary expression. Returns true
if the expression is | 630 * Determines the operand and result types of a binary expression. Returns true
if the expression is |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
839 std::move(test), | 825 std::move(test), |
840 std::move(ifTrue), | 826 std::move(ifTrue), |
841 std::move(ifFalse))
); | 827 std::move(ifFalse))
); |
842 } | 828 } |
843 | 829 |
844 std::unique_ptr<Expression> IRGenerator::call(Position position, | 830 std::unique_ptr<Expression> IRGenerator::call(Position position, |
845 const FunctionDeclaration& functio
n, | 831 const FunctionDeclaration& functio
n, |
846 std::vector<std::unique_ptr<Expres
sion>> arguments) { | 832 std::vector<std::unique_ptr<Expres
sion>> arguments) { |
847 if (function.fParameters.size() != arguments.size()) { | 833 if (function.fParameters.size() != arguments.size()) { |
848 std::string msg = "call to '" + function.fName + "' expected " + | 834 std::string msg = "call to '" + function.fName + "' expected " + |
849 to_string((uint64_t) function.fParameters.size(
)) + | 835 to_string(function.fParameters.size()) + |
850 " argument"; | 836 " argument"; |
851 if (function.fParameters.size() != 1) { | 837 if (function.fParameters.size() != 1) { |
852 msg += "s"; | 838 msg += "s"; |
853 } | 839 } |
854 msg += ", but found " + to_string((uint64_t) arguments.size()); | 840 msg += ", but found " + to_string(arguments.size()); |
855 fErrors.error(position, msg); | 841 fErrors.error(position, msg); |
856 return nullptr; | 842 return nullptr; |
857 } | 843 } |
858 for (size_t i = 0; i < arguments.size(); i++) { | 844 for (size_t i = 0; i < arguments.size(); i++) { |
859 arguments[i] = this->coerce(std::move(arguments[i]), function.fParameter
s[i]->fType); | 845 arguments[i] = this->coerce(std::move(arguments[i]), function.fParameter
s[i]->fType); |
860 if (arguments[i] && (function.fParameters[i]->fModifiers.fFlags & Modifi
ers::kOut_Flag)) { | 846 if (arguments[i] && (function.fParameters[i]->fModifiers.fFlags & Modifi
ers::kOut_Flag)) { |
861 this->markWrittenTo(*arguments[i]); | 847 this->markWrittenTo(*arguments[i]); |
862 } | 848 } |
863 } | 849 } |
864 return std::unique_ptr<FunctionCall>(new FunctionCall(position, function, | 850 return std::unique_ptr<FunctionCall>(new FunctionCall(position, function, |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
928 } | 914 } |
929 return this->call(position, *ref->fFunctions[0], std::move(arguments)); | 915 return this->call(position, *ref->fFunctions[0], std::move(arguments)); |
930 } | 916 } |
931 | 917 |
932 std::unique_ptr<Expression> IRGenerator::convertConstructor( | 918 std::unique_ptr<Expression> IRGenerator::convertConstructor( |
933 Position position, | 919 Position position, |
934 const Type& type, | 920 const Type& type, |
935 std::vector<std::unique_ptr<
Expression>> args) { | 921 std::vector<std::unique_ptr<
Expression>> args) { |
936 // FIXME: add support for structs and arrays | 922 // FIXME: add support for structs and arrays |
937 Type::Kind kind = type.kind(); | 923 Type::Kind kind = type.kind(); |
938 if (!type.isNumber() && kind != Type::kVector_Kind && kind != Type::kMatrix_
Kind && | 924 if (!type.isNumber() && kind != Type::kVector_Kind && kind != Type::kMatrix_
Kind) { |
939 kind != Type::kArray_Kind) { | |
940 fErrors.error(position, "cannot construct '" + type.description() + "'")
; | 925 fErrors.error(position, "cannot construct '" + type.description() + "'")
; |
941 return nullptr; | 926 return nullptr; |
942 } | 927 } |
943 if (type == *fContext.fFloat_Type && args.size() == 1 && | 928 if (type == *fContext.fFloat_Type && args.size() == 1 && |
944 args[0]->fKind == Expression::kIntLiteral_Kind) { | 929 args[0]->fKind == Expression::kIntLiteral_Kind) { |
945 int64_t value = ((IntLiteral&) *args[0]).fValue; | 930 int64_t value = ((IntLiteral&) *args[0]).fValue; |
946 return std::unique_ptr<Expression>(new FloatLiteral(fContext, position,
(double) value)); | 931 return std::unique_ptr<Expression>(new FloatLiteral(fContext, position,
(double) value)); |
947 } | 932 } |
948 if (args.size() == 1 && args[0]->fType == type) { | 933 if (args.size() == 1 && args[0]->fType == type) { |
949 // argument is already the right type, just return it | 934 // argument is already the right type, just return it |
950 return std::move(args[0]); | 935 return std::move(args[0]); |
951 } | 936 } |
952 if (type.isNumber()) { | 937 if (type.isNumber()) { |
953 if (args.size() != 1) { | 938 if (args.size() != 1) { |
954 fErrors.error(position, "invalid arguments to '" + type.description(
) + | 939 fErrors.error(position, "invalid arguments to '" + type.description(
) + |
955 "' constructor, (expected exactly 1 argument
, but found " + | 940 "' constructor, (expected exactly 1 argument
, but found " + |
956 to_string((uint64_t) args.size()) + ")"); | 941 to_string(args.size()) + ")"); |
957 } | 942 } |
958 if (args[0]->fType == *fContext.fBool_Type) { | 943 if (args[0]->fType == *fContext.fBool_Type) { |
959 std::unique_ptr<IntLiteral> zero(new IntLiteral(fContext, position,
0)); | 944 std::unique_ptr<IntLiteral> zero(new IntLiteral(fContext, position,
0)); |
960 std::unique_ptr<IntLiteral> one(new IntLiteral(fContext, position, 1
)); | 945 std::unique_ptr<IntLiteral> one(new IntLiteral(fContext, position, 1
)); |
961 return std::unique_ptr<Expression>( | 946 return std::unique_ptr<Expression>( |
962 new TernaryExpression(position, std::mo
ve(args[0]), | 947 new TernaryExpression(position, std::mo
ve(args[0]), |
963 this->coerce(std:
:move(one), type), | 948 this->coerce(std:
:move(one), type), |
964 this->coerce(std:
:move(zero), | 949 this->coerce(std:
:move(zero), |
965 type
))); | 950 type
))); |
966 } else if (!args[0]->fType.isNumber()) { | 951 } else if (!args[0]->fType.isNumber()) { |
967 fErrors.error(position, "invalid argument to '" + type.description()
+ | 952 fErrors.error(position, "invalid argument to '" + type.description()
+ |
968 "' constructor (expected a number or bool, b
ut found '" + | 953 "' constructor (expected a number or bool, b
ut found '" + |
969 args[0]->fType.description() + "')"); | 954 args[0]->fType.description() + "')"); |
970 } | 955 } |
971 if (args[0]->fKind == Expression::kIntLiteral_Kind && (type == *fContext
.fInt_Type || | |
972 type == *fContext.fUInt_Type)) { | |
973 return std::unique_ptr<Expression>(new IntLiteral(fContext, | |
974 position, | |
975 ((IntLiteral&) *ar
gs[0]).fValue, | |
976 &type)); | |
977 } | |
978 } else if (kind == Type::kArray_Kind) { | |
979 const Type& base = type.componentType(); | |
980 for (size_t i = 0; i < args.size(); i++) { | |
981 args[i] = this->coerce(std::move(args[i]), base); | |
982 } | |
983 } else { | 956 } else { |
984 ASSERT(kind == Type::kVector_Kind || kind == Type::kMatrix_Kind); | 957 ASSERT(kind == Type::kVector_Kind || kind == Type::kMatrix_Kind); |
985 int actual = 0; | 958 int actual = 0; |
986 for (size_t i = 0; i < args.size(); i++) { | 959 for (size_t i = 0; i < args.size(); i++) { |
987 if (args[i]->fType.kind() == Type::kVector_Kind || | 960 if (args[i]->fType.kind() == Type::kVector_Kind || |
988 args[i]->fType.kind() == Type::kMatrix_Kind) { | 961 args[i]->fType.kind() == Type::kMatrix_Kind) { |
989 int columns = args[i]->fType.columns(); | 962 int columns = args[i]->fType.columns(); |
990 int rows = args[i]->fType.rows(); | 963 int rows = args[i]->fType.rows(); |
991 args[i] = this->coerce(std::move(args[i]), | 964 args[i] = this->coerce(std::move(args[i]), |
992 type.componentType().toCompound(fContext,
columns, rows)); | 965 type.componentType().toCompound(fContext,
columns, rows)); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1074 break; | 1047 break; |
1075 default: | 1048 default: |
1076 ABORT("unsupported prefix operator\n"); | 1049 ABORT("unsupported prefix operator\n"); |
1077 } | 1050 } |
1078 return std::unique_ptr<Expression>(new PrefixExpression(expression.fOperator
, | 1051 return std::unique_ptr<Expression>(new PrefixExpression(expression.fOperator
, |
1079 std::move(base))); | 1052 std::move(base))); |
1080 } | 1053 } |
1081 | 1054 |
1082 std::unique_ptr<Expression> IRGenerator::convertIndex(std::unique_ptr<Expression
> base, | 1055 std::unique_ptr<Expression> IRGenerator::convertIndex(std::unique_ptr<Expression
> base, |
1083 const ASTExpression& index
) { | 1056 const ASTExpression& index
) { |
1084 if (base->fType.kind() != Type::kArray_Kind && base->fType.kind() != Type::k
Matrix_Kind && | 1057 if (base->fType.kind() != Type::kArray_Kind && base->fType.kind() != Type::k
Matrix_Kind) { |
1085 base->fType.kind() != Type::kVector_Kind) { | |
1086 fErrors.error(base->fPosition, "expected array, but found '" + base->fTy
pe.description() + | 1058 fErrors.error(base->fPosition, "expected array, but found '" + base->fTy
pe.description() + |
1087 "'"); | 1059 "'"); |
1088 return nullptr; | 1060 return nullptr; |
1089 } | 1061 } |
1090 std::unique_ptr<Expression> converted = this->convertExpression(index); | 1062 std::unique_ptr<Expression> converted = this->convertExpression(index); |
1091 if (!converted) { | 1063 if (!converted) { |
1092 return nullptr; | 1064 return nullptr; |
1093 } | 1065 } |
1094 if (converted->fType != *fContext.fUInt_Type) { | 1066 converted = this->coerce(std::move(converted), *fContext.fInt_Type); |
1095 converted = this->coerce(std::move(converted), *fContext.fInt_Type); | 1067 if (!converted) { |
1096 if (!converted) { | 1068 return nullptr; |
1097 return nullptr; | |
1098 } | |
1099 } | 1069 } |
1100 return std::unique_ptr<Expression>(new IndexExpression(fContext, std::move(b
ase), | 1070 return std::unique_ptr<Expression>(new IndexExpression(fContext, std::move(b
ase), |
1101 std::move(converted))
); | 1071 std::move(converted))
); |
1102 } | 1072 } |
1103 | 1073 |
1104 std::unique_ptr<Expression> IRGenerator::convertField(std::unique_ptr<Expression
> base, | 1074 std::unique_ptr<Expression> IRGenerator::convertField(std::unique_ptr<Expression
> base, |
1105 const std::string& field)
{ | 1075 const std::string& field)
{ |
1106 auto fields = base->fType.fields(); | 1076 auto fields = base->fType.fields(); |
1107 for (size_t i = 0; i < fields.size(); i++) { | 1077 for (size_t i = 0; i < fields.size(); i++) { |
1108 if (fields[i].fName == field) { | 1078 if (fields[i].fName == field) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1166 return std::unique_ptr<Expression>(new Swizzle(fContext, std::move(base), sw
izzleComponents)); | 1136 return std::unique_ptr<Expression>(new Swizzle(fContext, std::move(base), sw
izzleComponents)); |
1167 } | 1137 } |
1168 | 1138 |
1169 std::unique_ptr<Expression> IRGenerator::convertSuffixExpression( | 1139 std::unique_ptr<Expression> IRGenerator::convertSuffixExpression( |
1170 const ASTSuffixExpre
ssion& expression) { | 1140 const ASTSuffixExpre
ssion& expression) { |
1171 std::unique_ptr<Expression> base = this->convertExpression(*expression.fBase
); | 1141 std::unique_ptr<Expression> base = this->convertExpression(*expression.fBase
); |
1172 if (!base) { | 1142 if (!base) { |
1173 return nullptr; | 1143 return nullptr; |
1174 } | 1144 } |
1175 switch (expression.fSuffix->fKind) { | 1145 switch (expression.fSuffix->fKind) { |
1176 case ASTSuffix::kIndex_Kind: { | 1146 case ASTSuffix::kIndex_Kind: |
1177 const ASTExpression* expr = ((ASTIndexSuffix&) *expression.fSuffix).
fExpression.get(); | 1147 return this->convertIndex(std::move(base), |
1178 if (expr) { | 1148 *((ASTIndexSuffix&) *expression.fSuffix).f
Expression); |
1179 return this->convertIndex(std::move(base), *expr); | |
1180 } else if (base->fKind == Expression::kTypeReference_Kind) { | |
1181 const Type& oldType = ((TypeReference&) *base).fValue; | |
1182 Type* newType = new Type(oldType.name() + "[]", Type::kArray_Kin
d, oldType, | |
1183 -1); | |
1184 fSymbolTable->takeOwnership(newType); | |
1185 return std::unique_ptr<Expression>(new TypeReference(fContext, b
ase->fPosition, | |
1186 *newType)); | |
1187 } else { | |
1188 fErrors.error(expression.fPosition, "'[]' must follow a type nam
e"); | |
1189 } | |
1190 } | |
1191 case ASTSuffix::kCall_Kind: { | 1149 case ASTSuffix::kCall_Kind: { |
1192 auto rawArguments = &((ASTCallSuffix&) *expression.fSuffix).fArgumen
ts; | 1150 auto rawArguments = &((ASTCallSuffix&) *expression.fSuffix).fArgumen
ts; |
1193 std::vector<std::unique_ptr<Expression>> arguments; | 1151 std::vector<std::unique_ptr<Expression>> arguments; |
1194 for (size_t i = 0; i < rawArguments->size(); i++) { | 1152 for (size_t i = 0; i < rawArguments->size(); i++) { |
1195 std::unique_ptr<Expression> converted = | 1153 std::unique_ptr<Expression> converted = |
1196 this->convertExpression(*(*rawArguments)[i]); | 1154 this->convertExpression(*(*rawArguments)[i]); |
1197 if (!converted) { | 1155 if (!converted) { |
1198 return nullptr; | 1156 return nullptr; |
1199 } | 1157 } |
1200 arguments.push_back(std::move(converted)); | 1158 arguments.push_back(std::move(converted)); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1293 case Expression::kIndex_Kind: | 1251 case Expression::kIndex_Kind: |
1294 this->markWrittenTo(*((IndexExpression&) expr).fBase); | 1252 this->markWrittenTo(*((IndexExpression&) expr).fBase); |
1295 break; | 1253 break; |
1296 default: | 1254 default: |
1297 fErrors.error(expr.fPosition, "cannot assign to '" + expr.descriptio
n() + "'"); | 1255 fErrors.error(expr.fPosition, "cannot assign to '" + expr.descriptio
n() + "'"); |
1298 break; | 1256 break; |
1299 } | 1257 } |
1300 } | 1258 } |
1301 | 1259 |
1302 } | 1260 } |
OLD | NEW |