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

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

Issue 1984363002: initial checkin of SkSL compiler (Closed) Base URL: https://skia.googlesource.com/skia@master
Patch Set: documentation and cleanups Created 4 years, 6 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
OLDNEW
(Empty)
1 /*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "SkSLIRGenerator.h"
9
10 #include "limits.h"
11
12 #include "ast/SkSLASTBoolLiteral.h"
13 #include "ast/SkSLASTFieldSuffix.h"
14 #include "ast/SkSLASTFloatLiteral.h"
15 #include "ast/SkSLASTIndexSuffix.h"
16 #include "ast/SkSLASTIntLiteral.h"
17 #include "ir/SkSLBinaryExpression.h"
18 #include "ir/SkSLBoolLiteral.h"
19 #include "ir/SkSLBreakStatement.h"
20 #include "ir/SkSLConstructor.h"
21 #include "ir/SkSLContinueStatement.h"
22 #include "ir/SkSLDiscardStatement.h"
23 #include "ir/SkSLDoStatement.h"
24 #include "ir/SkSLExpressionStatement.h"
25 #include "ir/SkSLField.h"
26 #include "ir/SkSLFieldAccess.h"
27 #include "ir/SkSLFloatLiteral.h"
28 #include "ir/SkSLForStatement.h"
29 #include "ir/SkSLFunctionCall.h"
30 #include "ir/SkSLFunctionDeclaration.h"
31 #include "ir/SkSLFunctionDefinition.h"
32 #include "ir/SkSLFunctionReference.h"
33 #include "ir/SkSLIfStatement.h"
34 #include "ir/SkSLIndexExpression.h"
35 #include "ir/SkSLInterfaceBlock.h"
36 #include "ir/SkSLIntLiteral.h"
37 #include "ir/SkSLLayout.h"
38 #include "ir/SkSLPostfixExpression.h"
39 #include "ir/SkSLPrefixExpression.h"
40 #include "ir/SkSLReturnStatement.h"
41 #include "ir/SkSLSwizzle.h"
42 #include "ir/SkSLTernaryExpression.h"
43 #include "ir/SkSLUnresolvedFunction.h"
44 #include "ir/SkSLVariable.h"
45 #include "ir/SkSLVarDeclaration.h"
46 #include "ir/SkSLVarDeclarationStatement.h"
47 #include "ir/SkSLVariableReference.h"
48 #include "ir/SkSLWhileStatement.h"
49
50 namespace SkSL {
51
52 class AutoSymbolTable {
53 public:
54 AutoSymbolTable(IRGenerator* ir)
55 : fIR(ir)
56 , fPrevious(fIR->fSymbolTable) {
57 fIR->pushSymbolTable();
58 }
59
60 ~AutoSymbolTable() {
61 fIR->popSymbolTable();
62 ASSERT(fPrevious == fIR->fSymbolTable);
63 }
64
65 IRGenerator* fIR;
66 std::shared_ptr<SymbolTable> fPrevious;
67 };
68
69 IRGenerator::IRGenerator(std::shared_ptr<SymbolTable> symbolTable, ErrorReporter & errorReporter)
70 : fSymbolTable(symbolTable)
71 , fErrors(errorReporter) {
72 }
73
74 void IRGenerator::pushSymbolTable() {
75 fSymbolTable.reset(new SymbolTable(fSymbolTable));
76 }
77
78 void IRGenerator::popSymbolTable() {
79 fSymbolTable = fSymbolTable->fParent;
80 }
81
82 std::unique_ptr<Extension> IRGenerator::convertExtension(ASTExtension& extension ) {
83 return std::unique_ptr<Extension>(new Extension(extension.fPosition, extensi on.fName));
84 }
85
86 std::unique_ptr<Statement> IRGenerator::convertStatement(ASTStatement& statement ) {
87 switch (statement.fKind) {
88 case ASTStatement::kBlock_Kind:
89 return this->convertBlock((ASTBlock&) statement);
90 case ASTStatement::kVarDeclaration_Kind:
91 return this->convertVarDeclarationStatement((ASTVarDeclarationStatem ent&) statement);
92 case ASTStatement::kExpression_Kind:
93 return this->convertExpressionStatement((ASTExpressionStatement&) st atement);
94 case ASTStatement:: kIf_Kind:
95 return this->convertIf((ASTIfStatement&) statement);
96 case ASTStatement::kFor_Kind:
97 return this->convertFor((ASTForStatement&) statement);
98 case ASTStatement::kWhile_Kind:
99 return this->convertWhile((ASTWhileStatement&) statement);
100 case ASTStatement::kDo_Kind:
101 return this->convertDo((ASTDoStatement&) statement);
102 case ASTStatement::kReturn_Kind:
103 return this->convertReturn((ASTReturnStatement&) statement);
104 case ASTStatement::kBreak_Kind:
105 return this->convertBreak((ASTBreakStatement&) statement);
106 case ASTStatement::kContinue_Kind:
107 return this->convertContinue((ASTContinueStatement&) statement);
108 case ASTStatement::kDiscard_Kind:
109 return this->convertDiscard((ASTDiscardStatement&) statement);
110 default:
111 ABORT("unsupported statement type: %d\n", statement.fKind);
112 }
113 }
114
115 std::unique_ptr<Block> IRGenerator::convertBlock(ASTBlock& block) {
116 AutoSymbolTable table(this);
117 std::vector<std::unique_ptr<Statement>> statements;
118 for (size_t i = 0; i < block.fStatements.size(); i++) {
119 std::unique_ptr<Statement> statement = this->convertStatement(*block.fSt atements[i]);
120 if (statement == nullptr) {
121 return nullptr;
122 }
123 statements.push_back(std::move(statement));
124 }
125 return std::unique_ptr<Block>(new Block(block.fPosition, std::move(statement s)));
126 }
127
128 std::unique_ptr<Statement> IRGenerator::convertVarDeclarationStatement(
129 ASTVarDeclar ationStatement& s) {
130 auto result = new VarDeclarationStatement(this->convertVarDeclaration(*s.fDe claration,
131 Variabl e::kLocal_Storage));
132 return std::unique_ptr<Statement>(result);
133 }
134
135 Modifiers IRGenerator::convertModifiers(const ASTModifiers& modifiers) {
136 return Modifiers(modifiers);
137 }
138
139 std::unique_ptr<VarDeclaration> IRGenerator::convertVarDeclaration(ASTVarDeclara tion& decl,
140 Variable::Sto rage storage) {
141 std::vector<std::shared_ptr<Variable>> variables;
142 std::vector<std::vector<std::unique_ptr<Expression>>> sizes;
143 std::vector<std::unique_ptr<Expression>> values;
144 std::shared_ptr<Type> baseType = this->convertType(*decl.fType);
145 if (baseType == nullptr) {
146 return nullptr;
147 }
148 for (size_t i = 0; i < decl.fNames.size(); i++) {
149 Modifiers modifiers = this->convertModifiers(decl.fModifiers);
150 std::shared_ptr<Type> type = baseType;
151 std::vector<std::unique_ptr<Expression>> currentVarSizes;
152 for (size_t j = 0; j < decl.fSizes[i].size(); j++) {
153 if (decl.fSizes[i][j] != nullptr) {
154 ASTExpression& rawSize = *decl.fSizes[i][j];
155 std::unique_ptr<Expression> size = this->convertExpression(rawSi ze);
156 if (size == nullptr) {
157 return nullptr;
158 }
159 std::string name = type->fName;
160 uint64_t count;
161 if (size->fKind == Expression::kIntLiteral_Kind) {
162 count = ((IntLiteral&) *size).fValue;
163 name += "[" + to_string(count) + "]";
164 } else {
165 count = -1;
166 name += "[]";
167 }
168 type = std::shared_ptr<Type>(new Type(name, Type::kArray_Kind, t ype, (int) count));
169 currentVarSizes.push_back(std::move(size));
170 } else {
171 currentVarSizes.push_back(nullptr);
172 }
173 }
174 sizes.push_back(std::move(currentVarSizes));
175 auto var = std::shared_ptr<Variable>(new Variable(decl.fPosition, modifi ers,
176 decl.fNames[i], type, storage));
177 variables.push_back(var);
178 std::unique_ptr<Expression> value;
179 if (decl.fValues[i] != nullptr) {
180 value = this->convertExpression(*decl.fValues[i]);
181 if (value == nullptr) {
182 return nullptr;
183 }
184 value = this->coerce(std::move(value), type);
185 } else {
186 value = nullptr;
187 }
188 values.push_back(std::move(value));
189 fSymbolTable->add(var->fName, var);
190 }
191 return std::unique_ptr<VarDeclaration>(new VarDeclaration(decl.fPosition, va riables,
192 std::move(sizes), std::move(values)));
193 }
194
195 std::unique_ptr<Statement> IRGenerator::convertIf(ASTIfStatement& s) {
196 std::unique_ptr<Expression> test = this->convertExpression(*s.fTest);
197 if (test == nullptr) {
198 return nullptr;
199 }
200 std::unique_ptr<Statement> ifTrue = this->convertStatement(*s.fIfTrue);
201 if (ifTrue == nullptr) {
202 return nullptr;
203 }
204 std::unique_ptr<Statement> ifFalse;
205 if (s.fIfFalse != nullptr) {
206 ifFalse = this->convertStatement(*s.fIfFalse);
207 if (ifFalse == nullptr) {
208 return nullptr;
209 }
210 }
211 return std::unique_ptr<Statement>(new IfStatement(s.fPosition, std::move(tes t),
212 std::move(ifTrue), std::mo ve(ifFalse)));
213 }
214
215 std::unique_ptr<Statement> IRGenerator::convertFor(ASTForStatement& f) {
216 AutoSymbolTable table(this);
217 std::unique_ptr<Statement> initializer = this->convertStatement(*f.fInitiali zer);
218 if (initializer == nullptr) {
219 return nullptr;
220 }
221 std::unique_ptr<Expression> test = this->convertExpression(*f.fTest);
222 if (test == nullptr) {
223 return nullptr;
224 }
225 if (test->fType != kBool_Type) {
226 fErrors.error(f.fPosition, "expected 'bool', but found '" +
227 test->fType->description() + "'");
228 return nullptr;
229 }
230 std::unique_ptr<Expression> next = this->convertExpression(*f.fNext);
231 if (next == nullptr) {
232 return nullptr;
233 }
234 std::unique_ptr<Statement> statement = this->convertStatement(*f.fStatement) ;
235 if (statement == nullptr) {
236 return nullptr;
237 }
238 return std::unique_ptr<Statement>(new ForStatement(f.fPosition, std::move(in itializer),
239 std::move(test), std::mov e(next),
240 std::move(statement)));
241 }
242
243 std::unique_ptr<Statement> IRGenerator::convertWhile(ASTWhileStatement& w) {
244 std::unique_ptr<Expression> test = this->convertExpression(*w.fTest);
245 if (test == nullptr) {
246 return nullptr;
247 }
248 if (test->fType != kBool_Type) {
249 fErrors.error(w.fPosition, "expected 'bool', but found '" +
250 test->fType->description() + "'");
251 return nullptr;
252 }
253 std::unique_ptr<Statement> statement = this->convertStatement(*w.fStatement) ;
254 if (statement == nullptr) {
255 return nullptr;
256 }
257 return std::unique_ptr<Statement>(new WhileStatement(w.fPosition, std::move( test),
258 std::move(statement)));
259 }
260
261 std::unique_ptr<Statement> IRGenerator::convertDo(ASTDoStatement& d) {
262 std::unique_ptr<Expression> test = this->convertExpression(*d.fTest);
263 if (test == nullptr) {
264 return nullptr;
265 }
266 if (test->fType != kBool_Type) {
267 fErrors.error(d.fPosition, "expected 'bool', but found '" +
268 test->fType->description() + "'");
269 return nullptr;
270 }
271 std::unique_ptr<Statement> statement = this->convertStatement(*d.fStatement) ;
272 if (statement == nullptr) {
273 return nullptr;
274 }
275 return std::unique_ptr<Statement>(new DoStatement(d.fPosition, std::move(tes t),
276 std::move(statement)));
277 }
278
279 std::unique_ptr<Statement> IRGenerator::convertExpressionStatement(ASTExpression Statement& s) {
280 std::unique_ptr<Expression> e = this->convertExpression(*s.fExpression);
281 if (e == nullptr) {
282 return nullptr;
283 }
284 return std::unique_ptr<Statement>(new ExpressionStatement(std::move(e)));
285 }
286
287 std::unique_ptr<Statement> IRGenerator::convertReturn(ASTReturnStatement& r) {
288 if (r.fExpression) {
289 std::unique_ptr<Expression> result = this->convertExpression(*r.fExpress ion);
290 if (result == nullptr) {
291 return nullptr;
292 }
293 ASSERT(fCurrentFunction);
294 if (fCurrentFunction->fReturnType == kVoid_Type) {
295 fErrors.error(result->fPosition, "may not return a value from a void function");
296 }
297 result = this->coerce(std::move(result), fCurrentFunction->fReturnType);
298 return std::unique_ptr<Statement>(new ReturnStatement(std::move(result)) );
299 } else {
300 if (fCurrentFunction->fReturnType != kVoid_Type) {
301 fErrors.error(r.fPosition, "expected function to return '" +
302 fCurrentFunction->fReturnType->descriptio n() + "'");
303 }
304 return std::unique_ptr<Statement>(new ReturnStatement(r.fPosition));
305 }
306 }
307
308 std::unique_ptr<Statement> IRGenerator::convertBreak(ASTBreakStatement& b) {
309 return std::unique_ptr<Statement>(new BreakStatement(b.fPosition));
310 }
311
312 std::unique_ptr<Statement> IRGenerator::convertContinue(ASTContinueStatement& c) {
313 return std::unique_ptr<Statement>(new ContinueStatement(c.fPosition));
314 }
315
316 std::unique_ptr<Statement> IRGenerator::convertDiscard(ASTDiscardStatement& d) {
317 return std::unique_ptr<Statement>(new DiscardStatement(d.fPosition));
318 }
319
320 static std::shared_ptr<Type> expand_generics(std::shared_ptr<Type> type, int i) {
321 if (type->kind() == Type::kGeneric_Kind) {
322 return type->coercibleTypes()[i];
323 }
324 return type;
325 }
326
327 static void expand_generics(std::shared_ptr<FunctionDeclaration> decl,
328 std::shared_ptr<SymbolTable> symbolTable) {
329 for (int i = 0; i < 4; i++) {
330 std::shared_ptr<Type> returnType = expand_generics(decl->fReturnType, i) ;
331 std::vector<std::shared_ptr<Variable>> parameters;
332 for (auto p : decl->fParameters) {
333 parameters.push_back(std::shared_ptr<Variable>(new Variable(decl->fP osition,
334 Modifier s(p->fModifiers),
335 p->fName ,
336 expand_g enerics(p->fType,
337 i),
338 Variable::kP arameter_Storage)));
339 }
340 std::shared_ptr<FunctionDeclaration> expanded(new FunctionDeclaration(de cl->fPosition,
341 de cl->fName,
342 pa rameters,
343 re turnType));
344 symbolTable->add(expanded->fName, expanded);
345 }
346 }
347
348 std::unique_ptr<FunctionDefinition> IRGenerator::convertFunction(ASTFunction& f) {
349 std::shared_ptr<SymbolTable> old = fSymbolTable;
350 AutoSymbolTable table(this);
351 bool isGeneric;
352 std::shared_ptr<Type> returnType = this->convertType(*f.fReturnType);
353 if (returnType == nullptr) {
354 return nullptr;
355 }
356 isGeneric = returnType->kind() == Type::kGeneric_Kind;
357 std::vector<std::shared_ptr<Variable>> parameters;
358 for (size_t i = 0; i < f.fParameters.size(); i++) {
359 std::shared_ptr<Type> type = this->convertType(*f.fParameters[i]->fType) ;
360 if (type == nullptr) {
361 return nullptr;
362 }
363 for (int j = (int) f.fParameters[i]->fSizes.size() - 1; j >= 0; j--) {
364 int size = f.fParameters[i]->fSizes[j];
365 type = std::shared_ptr<Type>(new Type(type->name() + "[" + to_string (size) + "]",
366 Type::kArray_Kind, type, size) );
367 }
368 std::string name = f.fParameters[i]->fName;
369 Modifiers modifiers = this->convertModifiers(f.fParameters[i]->fModifier s);
370 Position pos = f.fParameters[i]->fPosition;
371 std::shared_ptr<Variable> var = std::shared_ptr<Variable>(new Variable(p os,
372 m odifiers,
373 n ame,
374 t ype,
375 Variable::k Parameter_Storage));
376 parameters.push_back(var);
377 isGeneric |= type->kind() == Type::kGeneric_Kind;
378 }
379
380 // find existing declaration
381 std::shared_ptr<FunctionDeclaration> decl;
382 auto entry = (*old)[f.fName];
383 if (entry) {
384 std::vector<std::shared_ptr<FunctionDeclaration>> functions;
385 switch (entry->fKind) {
386 case Symbol::kUnresolvedFunction_Kind:
387 functions = std::static_pointer_cast<UnresolvedFunction>(entry)- >fFunctions;
388 break;
389 case Symbol::kFunctionDeclaration_Kind:
390 functions.push_back(std::static_pointer_cast<FunctionDeclaration >(entry));
391 break;
392 default:
393 fErrors.error(f.fPosition, "symbol '" + f.fName + "' was already defined");
394 return nullptr;
395 }
396 for (auto other : functions) {
397 ASSERT(other->fName == f.fName);
398 if (parameters.size() == other->fParameters.size()) {
399 bool match = true;
400 for (size_t i = 0; i < parameters.size(); i++) {
401 if (parameters[i]->fType != other->fParameters[i]->fType) {
402 match = false;
403 break;
404 }
405 }
406 if (match) {
407 if (returnType != other->fReturnType) {
408 FunctionDeclaration newDecl = FunctionDeclaration(f.fPos ition,
409 f.fNam e,
410 parame ters,
411 return Type);
412 fErrors.error(f.fPosition, "functions '" + newDecl.descr iption() +
413 "' and '" + other->descriptio n() +
414 "' differ only in return valu e");
415 return nullptr;
416 }
417 decl = other;
418 for (size_t i = 0; i < parameters.size(); i++) {
419 fSymbolTable->add(parameters[i]->fName, decl->fParameter s[i]);
420 }
421 break;
422 }
423 }
424 }
425 }
426 if (!decl) {
427 // couldn't find an existing declaration
428 decl.reset(new FunctionDeclaration(f.fPosition, f.fName, parameters, ret urnType));
429 for (auto var : parameters) {
430 fSymbolTable->add(var->fName, var);
431 }
432 }
433
434 if (isGeneric) {
435 ASSERT(f.fBody == nullptr);
436 expand_generics(decl, old);
437 } else {
438 old->add(decl->fName, decl);
439 if (f.fBody != nullptr) {
440 ASSERT(fCurrentFunction == nullptr);
441 fCurrentFunction = decl;
442 std::unique_ptr<Block> body = this->convertBlock(*f.fBody);
443 fCurrentFunction = nullptr;
444 if (body == nullptr) {
445 return nullptr;
446 }
447 return std::unique_ptr<FunctionDefinition>(new FunctionDefinition(f. fPosition, decl,
448 st d::move(body)));
449 }
450 }
451 return nullptr;
452 }
453
454 std::unique_ptr<InterfaceBlock> IRGenerator::convertInterfaceBlock(ASTInterfaceB lock& intf) {
455 std::shared_ptr<SymbolTable> old = fSymbolTable;
456 AutoSymbolTable table(this);
457 Modifiers mods = this->convertModifiers(intf.fModifiers);
458 std::vector<Type::Field> fields;
459 for (size_t i = 0; i < intf.fDeclarations.size(); i++) {
460 std::unique_ptr<VarDeclaration> decl = this->convertVarDeclaration(*intf .fDeclarations[i],
461 Variable::kGloba l_Storage);
462 for (size_t j = 0; j < decl->fVars.size(); j++) {
463 fields.push_back(Type::Field(decl->fVars[j]->fModifiers, decl->fVars [j]->fName,
464 decl->fVars[j]->fType));
465 if (decl->fValues[j] != nullptr) {
466 fErrors.error(decl->fPosition, "initializers are not permitted o n interface block "
467 "fields");
468 }
469 }
470 }
471 std::shared_ptr<Type> type = std::shared_ptr<Type>(new Type(intf.fInterfaceN ame, fields));
472 std::string name = intf.fValueName.length() > 0 ? intf.fValueName : intf.fIn terfaceName;
473 std::shared_ptr<Variable> var = std::shared_ptr<Variable>(new Variable(intf. fPosition, mods,
474 name, type,
475 Variable::kGloba l_Storage));
476 if (intf.fValueName.length()) {
477 old->add(intf.fValueName, var);
478
479 } else {
480 for (size_t i = 0; i < fields.size(); i++) {
481 std::shared_ptr<Field> field = std::shared_ptr<Field>(new Field(intf .fPosition, var,
482 i));
483 old->add(fields[i].fName, field);
484 }
485 }
486 return std::unique_ptr<InterfaceBlock>(new InterfaceBlock(intf.fPosition, va r));
487 }
488
489 std::shared_ptr<Type> IRGenerator::convertType(ASTType& type) {
490 std::shared_ptr<Symbol> result = (*fSymbolTable)[type.fName];
491 if (result != nullptr && result->fKind == Symbol::kType_Kind) {
492 return std::static_pointer_cast<Type>(result);
493 }
494 fErrors.error(type.fPosition, "unknown type '" + type.fName + "'");
495 return nullptr;
496 }
497
498 std::unique_ptr<Expression> IRGenerator::convertExpression(ASTExpression& expr) {
499 switch (expr.fKind) {
500 case ASTExpression::kIdentifier_Kind:
501 return this->convertIdentifier((ASTIdentifier&) expr);
502 case ASTExpression::kBool_Kind:
503 return std::unique_ptr<Expression>(new BoolLiteral(expr.fPosition,
504 ((ASTBoolLiteral& ) expr).fValue));
505 case ASTExpression::kInt_Kind:
506 return std::unique_ptr<Expression>(new IntLiteral(expr.fPosition,
507 ((ASTIntLiteral&) expr).fValue));
508 case ASTExpression::kFloat_Kind:
509 return std::unique_ptr<Expression>(new FloatLiteral(expr.fPosition,
510 ((ASTFloatLitera l&) expr).fValue));
511 case ASTExpression::kBinary_Kind:
512 return this->convertBinaryExpression((ASTBinaryExpression&) expr);
513 case ASTExpression::kPrefix_Kind:
514 return this->convertPrefixExpression((ASTPrefixExpression&) expr);
515 case ASTExpression::kSuffix_Kind:
516 return this->convertSuffixExpression((ASTSuffixExpression&) expr);
517 case ASTExpression::kTernary_Kind:
518 return this->convertTernaryExpression((ASTTernaryExpression&) expr);
519 default:
520 ABORT("unsupported expression type: %d\n", expr.fKind);
521 }
522 }
523
524 std::unique_ptr<Expression> IRGenerator::convertIdentifier(ASTIdentifier& identi fier) {
525 std::shared_ptr<Symbol> result = (*fSymbolTable)[identifier.fText];
526 if (result == nullptr) {
527 fErrors.error(identifier.fPosition, "unknown identifier '" + identifier. fText + "'");
528 return nullptr;
529 }
530 switch (result->fKind) {
531 case Symbol::kFunctionDeclaration_Kind: {
532 std::vector<std::shared_ptr<FunctionDeclaration>> f;
533 f.push_back(std::static_pointer_cast<FunctionDeclaration>(result));
534 return std::unique_ptr<FunctionReference>(new FunctionReference(iden tifier.fPosition,
535 f));
536 }
537 case Symbol::kUnresolvedFunction_Kind: {
538 auto f = std::static_pointer_cast<UnresolvedFunction>(result);
539 return std::unique_ptr<FunctionReference>(new FunctionReference(iden tifier.fPosition,
540 f->f Functions));
541 }
542 case Symbol::kVariable_Kind: {
543 std::shared_ptr<Variable> var = std::static_pointer_cast<Variable>(r esult);
544 this->markReadFrom(var);
545 return std::unique_ptr<VariableReference>(new VariableReference(iden tifier.fPosition,
546 var) );
547 }
548 case Symbol::kField_Kind: {
549 std::shared_ptr<Field> field = std::static_pointer_cast<Field>(resul t);
550 VariableReference* base = new VariableReference(identifier.fPosition , field->fOwner);
551 return std::unique_ptr<Expression>(new FieldAccess(std::unique_ptr<E xpression>(base),
552 field->fFieldInde x));
553 }
554 case Symbol::kType_Kind: {
555 auto t = std::static_pointer_cast<Type>(result);
556 return std::unique_ptr<TypeReference>(new TypeReference(identifier.f Position, t));
557 }
558 default:
559 ABORT("unsupported symbol type %d\n", result->fKind);
560 }
561
562 }
563
564 std::unique_ptr<Expression> IRGenerator::coerce(std::unique_ptr<Expression> expr ,
565 std::shared_ptr<Type> type) {
566 if (*expr->fType == *type) {
567 return expr;
568 }
569 if (!expr->fType->canCoerceTo(type)) {
570 fErrors.error(expr->fPosition, "expected '" + type->description() + "', but found '" +
571 expr->fType->description() + "'");
572 return nullptr;
573 }
574 if (type->kind() == Type::kScalar_Kind) {
575 std::vector<std::unique_ptr<Expression>> parameters;
576 parameters.push_back(std::move(expr));
577 ASTIdentifier id(Position(), type->description());
578 std::unique_ptr<Expression> ctor = this->convertIdentifier(id);
579 ASSERT(ctor);
580 return this->call(Position(), std::move(ctor), std::move(parameters));
581 }
582 ABORT("cannot coerce %s to %s", expr->fType->description().c_str(), type->na me().c_str());
583 }
584
585 /**
586 * Determines the operand and result types of a binary expression. Returns true if the expression is
587 * legal, false otherwise. If false, the values of the out parameters are undefi ned.
588 */
589 static bool determine_binary_type(Token::Kind op, std::shared_ptr<Type> left,
590 std::shared_ptr<Type> right,
591 std::shared_ptr<Type>* outLeftType,
592 std::shared_ptr<Type>* outRightType,
593 std::shared_ptr<Type>* outResultType,
594 bool tryFlipped) {
595 if (op == Token::STAR || op == Token::STAREQ) {
596 if (left->kind() == Type::kMatrix_Kind && right->kind() == Type::kVector _Kind) {
597 *outLeftType = left;
598 *outRightType = right;
599 *outResultType = right;
600 return left->rows() == right->columns();
601 }
602 if (left->kind() == Type::kVector_Kind && right->kind() == Type::kMatrix _Kind) {
603 *outLeftType = left;
604 *outRightType = right;
605 *outResultType = left;
606 return left->columns() == right->columns();
607 }
608 }
609 bool isLogical;
610 switch (op) {
611 case Token::EQEQ: // fall through
612 case Token::NEQ: // fall through
613 case Token::LT: // fall through
614 case Token::GT: // fall through
615 case Token::LTEQ: // fall through
616 case Token::GTEQ:
617 isLogical = true;
618 break;
619 default:
620 isLogical = false;
621 }
622 // FIXME: need to disallow illegal operations like vec3 > vec3
623 if (left == right) {
624 *outLeftType = left;
625 *outRightType = left;
626 if (isLogical) {
627 *outResultType = kBool_Type;
628 } else {
629 *outResultType = left;
630 }
631 return true;
632 }
633 if (left->canCoerceTo(right)) {
634 *outLeftType = right;
635 *outRightType = right;
636 if (isLogical) {
637 *outResultType = kBool_Type;
638 } else {
639 *outResultType = right;
640 }
641 return true;
642 }
643 if ((left->columns() > 1) && (right->kind() == Type::kScalar_Kind)) {
644 if (determine_binary_type(op, left->componentType(), right, outLeftType, outRightType,
645 outResultType, false)) {
646 *outLeftType = (*outLeftType)->toCompound(left->columns(), left->row s());
647 if (!isLogical) {
648 *outResultType = (*outResultType)->toCompound(left->columns(), l eft->rows());
649 }
650 return true;
651 }
652 return false;
653 }
654 if (tryFlipped) {
655 return determine_binary_type(op, right, left, outRightType, outLeftType, outResultType,
656 false);
657 }
658 return false;
659 }
660
661 std::unique_ptr<Expression> IRGenerator::convertBinaryExpression(ASTBinaryExpres sion& expression) {
662 std::unique_ptr<Expression> left = this->convertExpression(*expression.fLeft );
663 if (left == nullptr) {
664 return nullptr;
665 }
666 std::unique_ptr<Expression> right = this->convertExpression(*expression.fRig ht);
667 if (right == nullptr) {
668 return nullptr;
669 }
670 std::shared_ptr<Type> leftType;
671 std::shared_ptr<Type> rightType;
672 std::shared_ptr<Type> resultType;
673 if (!determine_binary_type(expression.fOperator, left->fType, right->fType, &leftType,
674 &rightType, &resultType, true)) {
675 fErrors.error(expression.fPosition, "type mismatch: '" +
676 Token::OperatorName(expression.fOper ator) +
677 "' cannot operate on '" + left->fTyp e->fName +
678 "', '" + right->fType->fName + "'");
679 return nullptr;
680 }
681 switch (expression.fOperator) {
682 case Token::EQ: // fall through
683 case Token::PLUSEQ: // fall through
684 case Token::MINUSEQ: // fall through
685 case Token::STAREQ: // fall through
686 case Token::SLASHEQ: // fall through
687 case Token::PERCENTEQ: // fall through
688 case Token::SHLEQ: // fall through
689 case Token::SHREQ: // fall through
690 case Token::BITWISEOREQ: // fall through
691 case Token::BITWISEXOREQ: // fall through
692 case Token::BITWISEANDEQ: // fall through
693 case Token::LOGICALOREQ: // fall through
694 case Token::LOGICALXOREQ: // fall through
695 case Token::LOGICALANDEQ:
696 this->markWrittenTo(*left);
697 default:
698 break;
699 }
700 return std::unique_ptr<Expression>(new BinaryExpression(expression.fPosition ,
701 this->coerce(std::mo ve(left), leftType),
702 expression.fOperator ,
703 this->coerce(std::mo ve(right),
704 rightTy pe),
705 resultType));
706 }
707
708 std::unique_ptr<Expression> IRGenerator::convertTernaryExpression(ASTTernaryExpr ession& expression) {
709 std::unique_ptr<Expression> test = this->convertExpression(*expression.fTest );
710 if (test == nullptr) {
711 return nullptr;
712 }
713 test = this->coerce(std::move(test), kBool_Type);
714 std::unique_ptr<Expression> ifTrue = this->convertExpression(*expression.fIf True);
715 if (ifTrue == nullptr) {
716 return nullptr;
717 }
718 std::unique_ptr<Expression> ifFalse = this->convertExpression(*expression.fI fFalse);
719 if (ifFalse == nullptr) {
720 return nullptr;
721 }
722 std::shared_ptr<Type> trueType;
723 std::shared_ptr<Type> falseType;
724 std::shared_ptr<Type> resultType;
725 if (!determine_binary_type(Token::EQEQ, ifTrue->fType, ifFalse->fType, &true Type,
726 &falseType, &resultType, true)) {
727 fErrors.error(expression.fPosition, "ternary operator result mismatch: ' " +
728 ifTrue->fType->fName + "', '" +
729 ifFalse->fType->fName + "'");
730 return nullptr;
731 }
732 ASSERT(trueType == falseType);
733 ifTrue = this->coerce(std::move(ifTrue), trueType);
734 ifFalse = this->coerce(std::move(ifFalse), falseType);
735 return std::unique_ptr<Expression>(new TernaryExpression(expression.fPositio n,
736 std::move(test),
737 std::move(ifTrue),
738 std::move(ifFalse)) );
739 }
740
741 std::unique_ptr<Expression> IRGenerator::call(Position position,
742 std::shared_ptr<FunctionDeclaratio n> function,
743 std::vector<std::unique_ptr<Expres sion>> parameters) {
744 if (function->fParameters.size() != parameters.size()) {
745 std::string msg = "call to '" + function->fName + "' expected " +
746 to_string(function->fParameters.size()) +
747 " parameter";
748 if (function->fParameters.size() != 1) {
749 msg += "s";
750 }
751 msg += ", but found " + to_string(parameters.size());
752 fErrors.error(position, msg);
753 return nullptr;
754 }
755 for (size_t i = 0; i < parameters.size(); i++) {
756 parameters[i] = this->coerce(std::move(parameters[i]), function->fParame ters[i]->fType);
757 }
758 return std::unique_ptr<FunctionCall>(new FunctionCall(position, function,
759 std::move(parameters)) );
760 }
761
762 /**
763 * Determines the cost of coercing the parameters of a function to the required types. Returns true
764 * if the cost could be computed, false if the call is not valid. Cost has no pa rticular meaning
765 * other than "lower costs are preferred".
766 */
767 bool IRGenerator::determineCallCost(std::shared_ptr<FunctionDeclaration> functio n,
768 std::vector<std::unique_ptr<Expression>>& pa rameters,
769 int* outCost) {
770 if (function->fParameters.size() != parameters.size()) {
771 return false;
772 }
773 int total = 0;
774 for (size_t i = 0; i < parameters.size(); i++) {
775 int cost;
776 if (parameters[i]->fType->determineCoercionCost(function->fParameters[i] ->fType, &cost)) {
777 total += cost;
778 } else {
779 return false;
780 }
781 }
782 *outCost = total;
783 return true;
784 }
785
786 std::unique_ptr<Expression> IRGenerator::call(Position position,
787 std::unique_ptr<Expression> functi onValue,
788 std::vector<std::unique_ptr<Expres sion>> parameters) {
789 if (functionValue->fKind == Expression::kTypeReference_Kind) {
790 return this->convertConstructor(position,
791 ((TypeReference&) *functionValue).fValue ,
792 std::move(parameters));
793 }
794 if (functionValue->fKind != Expression::kFunctionReference_Kind) {
795 fErrors.error(position, "'" + functionValue->description() + "' is not a function");
796 return nullptr;
797 }
798 FunctionReference* ref = (FunctionReference*) functionValue.get();
799 int bestCost = INT_MAX;
800 std::shared_ptr<FunctionDeclaration> best;
801 if (ref->fFunctions.size() > 1) {
802 for (auto f : ref->fFunctions) {
803 int cost;
804 if (this->determineCallCost(f, parameters, &cost) && cost < bestCost ) {
805 bestCost = cost;
806 best = f;
807 }
808 }
809 if (best != nullptr) {
810 return this->call(position, best, std::move(parameters));
811 }
812 std::string msg = "no match for " + ref->fFunctions[0]->fName + "(";
813 std::string separator = "";
814 for (size_t i = 0; i < parameters.size(); i++) {
815 msg += separator;
816 separator = ", ";
817 msg += parameters[i]->fType->description();
818 }
819 msg += ")";
820 fErrors.error(position, msg);
821 return nullptr;
822 }
823 return this->call(position, ref->fFunctions[0], std::move(parameters));
824 }
825
826 std::unique_ptr<Expression> IRGenerator::convertConstructor(Position position,
827 std::shared_ptr<Type > type,
828 std::vector<std::unique_ptr<Ex pression>> params) {
829 if (type == kFloat_Type && params.size() == 1 &&
830 params[0]->fKind == Expression::kIntLiteral_Kind) {
831 int64_t value = ((IntLiteral&) *params[0]).fValue;
832 return std::unique_ptr<Expression>(new FloatLiteral(position, (double) v alue));
833 }
834 int min = type->rows() * type->columns();
835 int max = type->columns() > 1 ? INT_MAX : min;
836 int actual = 0;
837 for (size_t i = 0; i < params.size(); i++) {
838 if (params[i]->fType->kind() == Type::kScalar_Kind) {
839 actual += 1;
840 if (type->kind() != Type::kScalar_Kind) {
841 params[i] = coerce(std::move(params[i]), type->componentType());
842 }
843 } else {
844 actual += params[i]->fType->rows() * params[i]->fType->columns();
845 }
846 }
847 if ((type->kind() != Type::kVector_Kind || actual != 1) &&
848 (type->kind() != Type::kMatrix_Kind || actual != 1) &&
849 (actual < min || actual > max)) {
850 fErrors.error(position, "invalid parameters to '" + type->description() +
851 "' constructor (expected " + to_string(min) + " scalars, " +
852 "but found " + to_string(actual) + ")");
853 return nullptr;
854 }
855 if (type->isNumber()) {
856 ASSERT(params.size() == 1);
857 if (params[0]->fType == kBool_Type) {
858 return std::unique_ptr<Expression>(new TernaryExpression(position, s td::move(params[0]),
859 std::unique_ptr<Expression>(new IntLi teral(position, 1)),
860 std::unique_ptr<Expression>(new IntLite ral(position, 0))));
861 }
862 }
863 if (params.size() == 1 && params[0]->fType == type) {
864 // parameter is already the right type, just return it
865 return std::move(params[0]);
866 }
867 return std::unique_ptr<Expression>(new Constructor(position, type, std::move (params)));
868 }
869
870 std::unique_ptr<Expression> IRGenerator::convertPrefixExpression(ASTPrefixExpres sion& expression) {
871 std::unique_ptr<Expression> base = this->convertExpression(*expression.fOper and);
872 if (base == nullptr) {
873 return nullptr;
874 }
875 switch (expression.fOperator) {
876 case Token::PLUS:
877 if (!base->fType->isNumber() && base->fType->kind() != Type::kVector _Kind) {
878 fErrors.error(expression.fPosition,
879 "'+' cannot operate on '" + base->fType->descripti on() + "'");
880 return nullptr;
881 }
882 return base;
883 case Token::MINUS:
884 if (!base->fType->isNumber() && base->fType->kind() != Type::kVector _Kind) {
885 fErrors.error(expression.fPosition,
886 "'-' cannot operate on '" + base->fType->descripti on() + "'");
887 return nullptr;
888 }
889 if (base->fKind == Expression::kIntLiteral_Kind) {
890 return std::unique_ptr<Expression>(new IntLiteral(base->fPositio n,
891 -((IntLiteral& ) *base).fValue));
892 }
893 if (base->fKind == Expression::kFloatLiteral_Kind) {
894 double value = -((FloatLiteral&) *base).fValue;
895 return std::unique_ptr<Expression>(new FloatLiteral(base->fPosit ion, value));
896 }
897 return std::unique_ptr<Expression>(new PrefixExpression(Token::MINUS , std::move(base)));
898 case Token::PLUSPLUS:
899 if (!base->fType->isNumber() && base->fType->kind() != Type::kVector _Kind) {
900 fErrors.error(expression.fPosition,
901 "'" + Token::OperatorName(expression.fOperator) +
902 "' cannot operate on '" + base->fType->description () + "'");
903 return nullptr;
904 }
905 this->markWrittenTo(*base);
906 break;
907 case Token::MINUSMINUS:
908 if (!base->fType->isNumber()) {
909 fErrors.error(expression.fPosition,
910 "'" + Token::OperatorName(expression.fOperator) +
911 "' cannot operate on '" + base->fType->description () + "'");
912 return nullptr;
913 }
914 this->markWrittenTo(*base);
915 break;
916 case Token::NOT:
917 if (base->fType != kBool_Type) {
918 fErrors.error(expression.fPosition,
919 "'" + Token::OperatorName(expression.fOperator) +
920 "' cannot operate on '" + base->fType->description () + "'");
921 return nullptr;
922 }
923 break;
924 default:
925 ABORT("unsupported prefix operator\n");
926 }
927 return std::unique_ptr<Expression>(new PrefixExpression(expression.fOperator ,
928 std::move(base)));
929 }
930
931 std::unique_ptr<Expression> IRGenerator::convertIndex(std::unique_ptr<Expression > base,
932 ASTExpression& index) {
933 if (base->fType->kind() != Type::kArray_Kind && base->fType->kind() != Type: :kMatrix_Kind &&
934 base->fType->kind() != Type::kVector_Kind) {
935 fErrors.error(base->fPosition, "expected array, but found '" + base->fTy pe->description() +
936 "'");
937 return nullptr;
938 }
939 std::unique_ptr<Expression> converted = this->convertExpression(index);
940 if (converted == nullptr) {
941 return nullptr;
942 }
943 converted = this->coerce(std::move(converted), kInt_Type);
944 if (converted == nullptr) {
945 return nullptr;
946 }
947 return std::unique_ptr<Expression>(new IndexExpression(std::move(base), std: :move(converted)));
948 }
949
950 std::unique_ptr<Expression> IRGenerator::convertField(std::unique_ptr<Expression > base,
951 std::string field) {
952 auto fields = base->fType->fields();
953 for (size_t i = 0; i < fields.size(); i++) {
954 if (fields[i].fName == field) {
955 return std::unique_ptr<Expression>(new FieldAccess(std::move(base), i));
956 }
957 }
958 fErrors.error(base->fPosition, "type '" + base->fType->description() + "' do es not have a "
959 "field named '" + field + "");
960 return nullptr;
961 }
962
963 std::unique_ptr<Expression> IRGenerator::convertSwizzle(std::unique_ptr<Expressi on> base,
964 std::string fields) {
965 if (base->fType->columns() == 0) {
966 fErrors.error(base->fPosition, "cannot swizzle type '" + base->fType->de scription() + "'");
967 return nullptr;
968 }
969 std::vector<int> swizzleComponents;
970 for (char c : fields) {
971 switch (c) {
972 case 'x': // fall through
973 case 'r': // fall through
974 case 's':
975 swizzleComponents.push_back(0);
976 break;
977 case 'y': // fall through
978 case 'g': // fall through
979 case 't':
980 if (base->fType->columns() >= 2) {
981 swizzleComponents.push_back(1);
982 break;
983 }
984 // fall through
985 case 'z': // fall through
986 case 'b': // fall through
987 case 'p':
988 if (base->fType->columns() >= 3) {
989 swizzleComponents.push_back(2);
990 break;
991 }
992 // fall through
993 case 'w': // fall through
994 case 'a': // fall through
995 case 'q':
996 if (base->fType->columns() >= 4) {
997 swizzleComponents.push_back(3);
998 break;
999 }
1000 // fall through
1001 default:
1002 fErrors.error(base->fPosition, "invalid swizzle component '" + s td::string(1, c) +
1003 "'");
1004 return nullptr;
1005 }
1006 }
1007 ASSERT(swizzleComponents.size() > 0);
1008 if (swizzleComponents.size() > 4) {
1009 fErrors.error(base->fPosition, "too many components in swizzle mask '" + fields + "'");
1010 return nullptr;
1011 }
1012 return std::unique_ptr<Expression>(new Swizzle(std::move(base), swizzleCompo nents));
1013 }
1014
1015 std::unique_ptr<Expression> IRGenerator::convertSuffixExpression(ASTSuffixExpres sion& expression) {
1016 std::unique_ptr<Expression> base = convertExpression(*expression.fBase);
1017 if (base == nullptr) {
1018 return nullptr;
1019 }
1020 switch (expression.fSuffix->fKind) {
1021 case ASTSuffix::kIndex_Kind:
1022 return convertIndex(std::move(base),
1023 *((ASTIndexSuffix&) *expression.fSuffix).fExpres sion);
1024 case ASTSuffix::kCall_Kind: {
1025 auto rawParameters = &((ASTCallSuffix&) *expression.fSuffix).fParame ters;
1026 std::vector<std::unique_ptr<Expression>> parameters;
1027 for (size_t i = 0; i < rawParameters->size(); i++) {
1028 std::unique_ptr<Expression> converted = this->convertExpression(
1029 *( *rawParameters)[i]);
1030 if (converted == nullptr) {
1031 return nullptr;
1032 }
1033 parameters.push_back(std::move(converted));
1034 }
1035 return this->call(expression.fPosition, std::move(base), std::move(p arameters));
1036 }
1037 case ASTSuffix::kField_Kind: {
1038 std::string field = ((ASTFieldSuffix&) *expression.fSuffix).fField;
1039 switch (base->fType->kind()) {
1040 case Type::kVector_Kind:
1041 return convertSwizzle(std::move(base), field);
1042 case Type::kStruct_Kind:
1043 return convertField(std::move(base), field);
1044 default:
1045 fErrors.error(base->fPosition, "cannot swizzle value of type '" +
1046 base->fType->description() + "'");
1047 return nullptr;
1048 }
1049 }
1050 case ASTSuffix::kPostIncrement_Kind:
1051 this->markWrittenTo(*base);
1052 return std::unique_ptr<Expression>(new PostfixExpression(std::move(b ase),
1053 Token::PLUS PLUS));
1054 case ASTSuffix::kPostDecrement_Kind:
1055 this->markWrittenTo(*base);
1056 return std::unique_ptr<Expression>(new PostfixExpression(std::move(b ase),
1057 Token::MINU SMINUS));
1058 default:
1059 ABORT("unsupported suffix operator");
1060 }
1061 }
1062
1063 void IRGenerator::markReadFrom(std::shared_ptr<Variable> var) {
1064 var->fIsReadFrom = true;
1065 }
1066
1067 void IRGenerator::markWrittenTo(Expression& expr) {
1068 switch (expr.fKind) {
1069 case Expression::kVariableReference_Kind:
1070 ((VariableReference&) expr).fVariable->fIsWrittenTo = true;
1071 break;
1072 case Expression::kFieldAccess_Kind:
1073 this->markWrittenTo(*((FieldAccess&) expr).fBase);
1074 break;
1075 case Expression::kSwizzle_Kind:
1076 this->markWrittenTo(*((Swizzle&) expr).fBase);
1077 break;
1078 case Expression::kIndex_Kind:
1079 this->markWrittenTo(*((IndexExpression&) expr).fBase);
1080 break;
1081 default:
1082 fErrors.error(expr.fPosition, "cannot assign to '" + expr.descriptio n() + "'");
1083 break;
1084 }
1085 }
1086
1087 }
OLDNEW
« src/gpu/vk/GrVkGpu.h ('K') | « src/sksl/SkSLIRGenerator.h ('k') | src/sksl/SkSLParser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698