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 "src/sksl/SkSLIRGenerator.h"
9
10#include "limits.h"
11#include <unordered_set>
12
13#include "src/sksl/SkSLCompiler.h"
14#include "src/sksl/SkSLParser.h"
15#include "src/sksl/ir/SkSLBinaryExpression.h"
16#include "src/sksl/ir/SkSLBoolLiteral.h"
17#include "src/sksl/ir/SkSLBreakStatement.h"
18#include "src/sksl/ir/SkSLConstructor.h"
19#include "src/sksl/ir/SkSLContinueStatement.h"
20#include "src/sksl/ir/SkSLDiscardStatement.h"
21#include "src/sksl/ir/SkSLDoStatement.h"
22#include "src/sksl/ir/SkSLEnum.h"
23#include "src/sksl/ir/SkSLExpressionStatement.h"
24#include "src/sksl/ir/SkSLExternalFunctionCall.h"
25#include "src/sksl/ir/SkSLExternalValueReference.h"
26#include "src/sksl/ir/SkSLField.h"
27#include "src/sksl/ir/SkSLFieldAccess.h"
28#include "src/sksl/ir/SkSLFloatLiteral.h"
29#include "src/sksl/ir/SkSLForStatement.h"
30#include "src/sksl/ir/SkSLFunctionCall.h"
31#include "src/sksl/ir/SkSLFunctionDeclaration.h"
32#include "src/sksl/ir/SkSLFunctionDefinition.h"
33#include "src/sksl/ir/SkSLFunctionReference.h"
34#include "src/sksl/ir/SkSLIfStatement.h"
35#include "src/sksl/ir/SkSLIndexExpression.h"
36#include "src/sksl/ir/SkSLIntLiteral.h"
37#include "src/sksl/ir/SkSLInterfaceBlock.h"
38#include "src/sksl/ir/SkSLLayout.h"
39#include "src/sksl/ir/SkSLNop.h"
40#include "src/sksl/ir/SkSLNullLiteral.h"
41#include "src/sksl/ir/SkSLPostfixExpression.h"
42#include "src/sksl/ir/SkSLPrefixExpression.h"
43#include "src/sksl/ir/SkSLReturnStatement.h"
44#include "src/sksl/ir/SkSLSetting.h"
45#include "src/sksl/ir/SkSLSwitchCase.h"
46#include "src/sksl/ir/SkSLSwitchStatement.h"
47#include "src/sksl/ir/SkSLSwizzle.h"
48#include "src/sksl/ir/SkSLTernaryExpression.h"
49#include "src/sksl/ir/SkSLUnresolvedFunction.h"
50#include "src/sksl/ir/SkSLVarDeclarations.h"
51#include "src/sksl/ir/SkSLVarDeclarationsStatement.h"
52#include "src/sksl/ir/SkSLVariable.h"
53#include "src/sksl/ir/SkSLVariableReference.h"
54#include "src/sksl/ir/SkSLWhileStatement.h"
55
56namespace SkSL {
57
58class AutoSymbolTable {
59public:
60 AutoSymbolTable(IRGenerator* ir)
61 : fIR(ir)
62 , fPrevious(fIR->fSymbolTable) {
63 fIR->pushSymbolTable();
64 }
65
66 ~AutoSymbolTable() {
67 fIR->popSymbolTable();
68 SkASSERT(fPrevious == fIR->fSymbolTable);
69 }
70
71 IRGenerator* fIR;
72 std::shared_ptr<SymbolTable> fPrevious;
73};
74
75class AutoLoopLevel {
76public:
77 AutoLoopLevel(IRGenerator* ir)
78 : fIR(ir) {
79 fIR->fLoopLevel++;
80 }
81
82 ~AutoLoopLevel() {
83 fIR->fLoopLevel--;
84 }
85
86 IRGenerator* fIR;
87};
88
89class AutoSwitchLevel {
90public:
91 AutoSwitchLevel(IRGenerator* ir)
92 : fIR(ir) {
93 fIR->fSwitchLevel++;
94 }
95
96 ~AutoSwitchLevel() {
97 fIR->fSwitchLevel--;
98 }
99
100 IRGenerator* fIR;
101};
102
103IRGenerator::IRGenerator(const Context* context, std::shared_ptr<SymbolTable> symbolTable,
104 ErrorReporter& errorReporter)
105: fContext(*context)
106, fCurrentFunction(nullptr)
107, fRootSymbolTable(symbolTable)
108, fSymbolTable(symbolTable)
109, fLoopLevel(0)
110, fSwitchLevel(0)
111, fErrors(errorReporter) {}
112
113void IRGenerator::pushSymbolTable() {
114 fSymbolTable.reset(new SymbolTable(std::move(fSymbolTable), &fErrors));
115}
116
117void IRGenerator::popSymbolTable() {
118 fSymbolTable = fSymbolTable->fParent;
119}
120
121static void fill_caps(const SKSL_CAPS_CLASS& caps,
122 std::unordered_map<String, Program::Settings::Value>* capsMap) {
123#define CAP(name) \
124 capsMap->insert(std::make_pair(String(#name), Program::Settings::Value(caps.name())))
125 CAP(fbFetchSupport);
126 CAP(fbFetchNeedsCustomOutput);
127 CAP(flatInterpolationSupport);
128 CAP(noperspectiveInterpolationSupport);
129 CAP(externalTextureSupport);
130 CAP(mustEnableAdvBlendEqs);
131 CAP(mustEnableSpecificAdvBlendEqs);
132 CAP(mustDeclareFragmentShaderOutput);
133 CAP(mustDoOpBetweenFloorAndAbs);
134 CAP(mustGuardDivisionEvenAfterExplicitZeroCheck);
135 CAP(inBlendModesFailRandomlyForAllZeroVec);
136 CAP(atan2ImplementedAsAtanYOverX);
137 CAP(canUseAnyFunctionInShader);
138 CAP(floatIs32Bits);
139 CAP(integerSupport);
140#undef CAP
141}
142
143void IRGenerator::start(const Program::Settings* settings,
144 std::vector<std::unique_ptr<ProgramElement>>* inherited) {
145 fSettings = settings;
146 fCapsMap.clear();
147 if (settings->fCaps) {
148 fill_caps(*settings->fCaps, &fCapsMap);
149 } else {
150 fCapsMap.insert(std::make_pair(String("integerSupport"),
151 Program::Settings::Value(true)));
152 }
153 this->pushSymbolTable();
154 fInvocations = -1;
155 fInputs.reset();
156 fSkPerVertex = nullptr;
157 fRTAdjust = nullptr;
158 fRTAdjustInterfaceBlock = nullptr;
159 if (inherited) {
160 for (const auto& e : *inherited) {
161 if (e->fKind == ProgramElement::kInterfaceBlock_Kind) {
162 InterfaceBlock& intf = (InterfaceBlock&) *e;
163 if (intf.fVariable.fName == Compiler::PERVERTEX_NAME) {
164 SkASSERT(!fSkPerVertex);
165 fSkPerVertex = &intf.fVariable;
166 }
167 }
168 }
169 }
170 SkASSERT(fIntrinsics);
171 for (auto& pair : *fIntrinsics) {
172 pair.second.second = false;
173 }
174}
175
176std::unique_ptr<Extension> IRGenerator::convertExtension(int offset, StringFragment name) {
177 return std::unique_ptr<Extension>(new Extension(offset, name));
178}
179
180void IRGenerator::finish() {
181 this->popSymbolTable();
182 fSettings = nullptr;
183}
184
185std::unique_ptr<Statement> IRGenerator::convertStatement(const ASTNode& statement) {
186 switch (statement.fKind) {
187 case ASTNode::Kind::kBlock:
188 return this->convertBlock(statement);
189 case ASTNode::Kind::kVarDeclarations:
190 return this->convertVarDeclarationStatement(statement);
191 case ASTNode::Kind::kIf:
192 return this->convertIf(statement);
193 case ASTNode::Kind::kFor:
194 return this->convertFor(statement);
195 case ASTNode::Kind::kWhile:
196 return this->convertWhile(statement);
197 case ASTNode::Kind::kDo:
198 return this->convertDo(statement);
199 case ASTNode::Kind::kSwitch:
200 return this->convertSwitch(statement);
201 case ASTNode::Kind::kReturn:
202 return this->convertReturn(statement);
203 case ASTNode::Kind::kBreak:
204 return this->convertBreak(statement);
205 case ASTNode::Kind::kContinue:
206 return this->convertContinue(statement);
207 case ASTNode::Kind::kDiscard:
208 return this->convertDiscard(statement);
209 default:
210 // it's an expression
211 std::unique_ptr<Statement> result = this->convertExpressionStatement(statement);
212 if (fRTAdjust && Program::kGeometry_Kind == fKind) {
213 SkASSERT(result->fKind == Statement::kExpression_Kind);
214 Expression& expr = *((ExpressionStatement&) *result).fExpression;
215 if (expr.fKind == Expression::kFunctionCall_Kind) {
216 FunctionCall& fc = (FunctionCall&) expr;
217 if (fc.fFunction.fBuiltin && fc.fFunction.fName == "EmitVertex") {
218 std::vector<std::unique_ptr<Statement>> statements;
219 statements.push_back(getNormalizeSkPositionCode());
220 statements.push_back(std::move(result));
221 return std::unique_ptr<Block>(new Block(statement.fOffset,
222 std::move(statements),
223 fSymbolTable));
224 }
225 }
226 }
227 return result;
228 }
229}
230
231std::unique_ptr<Block> IRGenerator::convertBlock(const ASTNode& block) {
232 SkASSERT(block.fKind == ASTNode::Kind::kBlock);
233 AutoSymbolTable table(this);
234 std::vector<std::unique_ptr<Statement>> statements;
235 for (const auto& child : block) {
236 std::unique_ptr<Statement> statement = this->convertStatement(child);
237 if (!statement) {
238 return nullptr;
239 }
240 statements.push_back(std::move(statement));
241 }
242 return std::unique_ptr<Block>(new Block(block.fOffset, std::move(statements), fSymbolTable));
243}
244
245std::unique_ptr<Statement> IRGenerator::convertVarDeclarationStatement(const ASTNode& s) {
246 SkASSERT(s.fKind == ASTNode::Kind::kVarDeclarations);
247 auto decl = this->convertVarDeclarations(s, Variable::kLocal_Storage);
248 if (!decl) {
249 return nullptr;
250 }
251 return std::unique_ptr<Statement>(new VarDeclarationsStatement(std::move(decl)));
252}
253
254std::unique_ptr<VarDeclarations> IRGenerator::convertVarDeclarations(const ASTNode& decls,
255 Variable::Storage storage) {
256 SkASSERT(decls.fKind == ASTNode::Kind::kVarDeclarations);
257 auto iter = decls.begin();
258 const Modifiers& modifiers = iter++->getModifiers();
259 const ASTNode& rawType = *(iter++);
260 std::vector<std::unique_ptr<VarDeclaration>> variables;
261 const Type* baseType = this->convertType(rawType);
262 if (!baseType) {
263 return nullptr;
264 }
265 if (fKind != Program::kFragmentProcessor_Kind) {
266 if ((modifiers.fFlags & Modifiers::kIn_Flag) &&
267 baseType->kind() == Type::Kind::kMatrix_Kind) {
268 fErrors.error(decls.fOffset, "'in' variables may not have matrix type");
269 }
270 if ((modifiers.fFlags & Modifiers::kIn_Flag) &&
271 (modifiers.fFlags & Modifiers::kUniform_Flag)) {
272 fErrors.error(decls.fOffset,
273 "'in uniform' variables only permitted within fragment processors");
274 }
275 if (modifiers.fLayout.fWhen.fLength) {
276 fErrors.error(decls.fOffset, "'when' is only permitted within fragment processors");
277 }
278 if (modifiers.fLayout.fFlags & Layout::kTracked_Flag) {
279 fErrors.error(decls.fOffset, "'tracked' is only permitted within fragment processors");
280 }
281 if (modifiers.fLayout.fCType != Layout::CType::kDefault) {
282 fErrors.error(decls.fOffset, "'ctype' is only permitted within fragment processors");
283 }
284 if (modifiers.fLayout.fKey) {
285 fErrors.error(decls.fOffset, "'key' is only permitted within fragment processors");
286 }
287 }
288 if (modifiers.fLayout.fKey && (modifiers.fFlags & Modifiers::kUniform_Flag)) {
289 fErrors.error(decls.fOffset, "'key' is not permitted on 'uniform' variables");
290 }
291 if (modifiers.fFlags & Modifiers::kVarying_Flag) {
292 if (fKind != Program::kPipelineStage_Kind) {
293 fErrors.error(decls.fOffset, "'varying' is only permitted in runtime effects");
294 }
295 if (!baseType->isFloat() &&
296 !(baseType->kind() == Type::kVector_Kind && baseType->componentType().isFloat())) {
297 fErrors.error(decls.fOffset, "'varying' must be float scalar or vector");
298 }
299 }
300 for (; iter != decls.end(); ++iter) {
301 const ASTNode& varDecl = *iter;
302 if (modifiers.fLayout.fLocation == 0 && modifiers.fLayout.fIndex == 0 &&
303 (modifiers.fFlags & Modifiers::kOut_Flag) && fKind == Program::kFragment_Kind &&
304 varDecl.getVarData().fName != "sk_FragColor") {
305 fErrors.error(varDecl.fOffset,
306 "out location=0, index=0 is reserved for sk_FragColor");
307 }
308 const ASTNode::VarData& varData = varDecl.getVarData();
309 const Type* type = baseType;
310 std::vector<std::unique_ptr<Expression>> sizes;
311 auto iter = varDecl.begin();
312 if (varData.fSizeCount > 0 && (modifiers.fFlags & Modifiers::kIn_Flag)) {
313 fErrors.error(varDecl.fOffset, "'in' variables may not have array type");
314 }
315 for (size_t i = 0; i < varData.fSizeCount; ++i, ++iter) {
316 const ASTNode& rawSize = *iter;
317 if (rawSize) {
318 auto size = this->coerce(this->convertExpression(rawSize), *fContext.fInt_Type);
319 if (!size) {
320 return nullptr;
321 }
322 String name(type->fName);
323 int64_t count;
324 if (size->fKind == Expression::kIntLiteral_Kind) {
325 count = ((IntLiteral&) *size).fValue;
326 if (count <= 0) {
327 fErrors.error(size->fOffset, "array size must be positive");
328 return nullptr;
329 }
330 name += "[" + to_string(count) + "]";
331 } else {
332 fErrors.error(size->fOffset, "array size must be specified");
333 return nullptr;
334 }
335 type = (Type*) fSymbolTable->takeOwnership(
336 std::unique_ptr<Symbol>(new Type(name,
337 Type::kArray_Kind,
338 *type,
339 (int) count)));
340 sizes.push_back(std::move(size));
341 } else {
342 type = (Type*) fSymbolTable->takeOwnership(
343 std::unique_ptr<Symbol>(new Type(type->name() + "[]",
344 Type::kArray_Kind,
345 *type,
346 -1)));
347 sizes.push_back(nullptr);
348 }
349 }
350 auto var = std::unique_ptr<Variable>(new Variable(varDecl.fOffset, modifiers,
351 varData.fName, *type, storage));
352 if (var->fName == Compiler::RTADJUST_NAME) {
353 SkASSERT(!fRTAdjust);
354 SkASSERT(var->fType == *fContext.fFloat4_Type);
355 fRTAdjust = var.get();
356 }
357 std::unique_ptr<Expression> value;
358 if (iter != varDecl.end()) {
359 value = this->convertExpression(*iter);
360 if (!value) {
361 return nullptr;
362 }
363 value = this->coerce(std::move(value), *type);
364 if (!value) {
365 return nullptr;
366 }
367 var->fWriteCount = 1;
368 var->fInitialValue = value.get();
369 }
370 if (storage == Variable::kGlobal_Storage && var->fName == "sk_FragColor" &&
371 (*fSymbolTable)[var->fName]) {
372 // already defined, ignore
373 } else if (storage == Variable::kGlobal_Storage && (*fSymbolTable)[var->fName] &&
374 (*fSymbolTable)[var->fName]->fKind == Symbol::kVariable_Kind &&
375 ((Variable*) (*fSymbolTable)[var->fName])->fModifiers.fLayout.fBuiltin >= 0) {
376 // already defined, just update the modifiers
377 Variable* old = (Variable*) (*fSymbolTable)[var->fName];
378 old->fModifiers = var->fModifiers;
379 } else {
380 variables.emplace_back(new VarDeclaration(var.get(), std::move(sizes),
381 std::move(value)));
382 StringFragment name = var->fName;
383 fSymbolTable->add(name, std::move(var));
384 }
385 }
386 return std::unique_ptr<VarDeclarations>(new VarDeclarations(decls.fOffset,
387 baseType,
388 std::move(variables)));
389}
390
391std::unique_ptr<ModifiersDeclaration> IRGenerator::convertModifiersDeclaration(const ASTNode& m) {
392 SkASSERT(m.fKind == ASTNode::Kind::kModifiers);
393 Modifiers modifiers = m.getModifiers();
394 if (modifiers.fLayout.fInvocations != -1) {
395 if (fKind != Program::kGeometry_Kind) {
396 fErrors.error(m.fOffset, "'invocations' is only legal in geometry shaders");
397 return nullptr;
398 }
399 fInvocations = modifiers.fLayout.fInvocations;
400 if (fSettings->fCaps && !fSettings->fCaps->gsInvocationsSupport()) {
401 modifiers.fLayout.fInvocations = -1;
402 Variable* invocationId = (Variable*) (*fSymbolTable)["sk_InvocationID"];
403 SkASSERT(invocationId);
404 invocationId->fModifiers.fFlags = 0;
405 invocationId->fModifiers.fLayout.fBuiltin = -1;
406 if (modifiers.fLayout.description() == "") {
407 return nullptr;
408 }
409 }
410 }
411 if (modifiers.fLayout.fMaxVertices != -1 && fInvocations > 0 && fSettings->fCaps &&
412 !fSettings->fCaps->gsInvocationsSupport()) {
413 modifiers.fLayout.fMaxVertices *= fInvocations;
414 }
415 return std::unique_ptr<ModifiersDeclaration>(new ModifiersDeclaration(modifiers));
416}
417
418std::unique_ptr<Statement> IRGenerator::convertIf(const ASTNode& n) {
419 SkASSERT(n.fKind == ASTNode::Kind::kIf);
420 auto iter = n.begin();
421 std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*(iter++)),
422 *fContext.fBool_Type);
423 if (!test) {
424 return nullptr;
425 }
426 std::unique_ptr<Statement> ifTrue = this->convertStatement(*(iter++));
427 if (!ifTrue) {
428 return nullptr;
429 }
430 std::unique_ptr<Statement> ifFalse;
431 if (iter != n.end()) {
432 ifFalse = this->convertStatement(*(iter++));
433 if (!ifFalse) {
434 return nullptr;
435 }
436 }
437 if (test->fKind == Expression::kBoolLiteral_Kind) {
438 // static boolean value, fold down to a single branch
439 if (((BoolLiteral&) *test).fValue) {
440 return ifTrue;
441 } else if (ifFalse) {
442 return ifFalse;
443 } else {
444 // False & no else clause. Not an error, so don't return null!
445 std::vector<std::unique_ptr<Statement>> empty;
446 return std::unique_ptr<Statement>(new Block(n.fOffset, std::move(empty),
447 fSymbolTable));
448 }
449 }
450 return std::unique_ptr<Statement>(new IfStatement(n.fOffset, n.getBool(), std::move(test),
451 std::move(ifTrue), std::move(ifFalse)));
452}
453
454std::unique_ptr<Statement> IRGenerator::convertFor(const ASTNode& f) {
455 SkASSERT(f.fKind == ASTNode::Kind::kFor);
456 AutoLoopLevel level(this);
457 AutoSymbolTable table(this);
458 std::unique_ptr<Statement> initializer;
459 auto iter = f.begin();
460 if (*iter) {
461 initializer = this->convertStatement(*iter);
462 if (!initializer) {
463 return nullptr;
464 }
465 }
466 ++iter;
467 std::unique_ptr<Expression> test;
468 if (*iter) {
469 test = this->coerce(this->convertExpression(*iter), *fContext.fBool_Type);
470 if (!test) {
471 return nullptr;
472 }
473 }
474 ++iter;
475 std::unique_ptr<Expression> next;
476 if (*iter) {
477 next = this->convertExpression(*iter);
478 if (!next) {
479 return nullptr;
480 }
481 this->checkValid(*next);
482 }
483 ++iter;
484 std::unique_ptr<Statement> statement = this->convertStatement(*iter);
485 if (!statement) {
486 return nullptr;
487 }
488 return std::unique_ptr<Statement>(new ForStatement(f.fOffset, std::move(initializer),
489 std::move(test), std::move(next),
490 std::move(statement), fSymbolTable));
491}
492
493std::unique_ptr<Statement> IRGenerator::convertWhile(const ASTNode& w) {
494 SkASSERT(w.fKind == ASTNode::Kind::kWhile);
495 AutoLoopLevel level(this);
496 auto iter = w.begin();
497 std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*(iter++)),
498 *fContext.fBool_Type);
499 if (!test) {
500 return nullptr;
501 }
502 std::unique_ptr<Statement> statement = this->convertStatement(*(iter++));
503 if (!statement) {
504 return nullptr;
505 }
506 return std::unique_ptr<Statement>(new WhileStatement(w.fOffset, std::move(test),
507 std::move(statement)));
508}
509
510std::unique_ptr<Statement> IRGenerator::convertDo(const ASTNode& d) {
511 SkASSERT(d.fKind == ASTNode::Kind::kDo);
512 AutoLoopLevel level(this);
513 auto iter = d.begin();
514 std::unique_ptr<Statement> statement = this->convertStatement(*(iter++));
515 if (!statement) {
516 return nullptr;
517 }
518 std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*(iter++)),
519 *fContext.fBool_Type);
520 if (!test) {
521 return nullptr;
522 }
523 return std::unique_ptr<Statement>(new DoStatement(d.fOffset, std::move(statement),
524 std::move(test)));
525}
526
527std::unique_ptr<Statement> IRGenerator::convertSwitch(const ASTNode& s) {
528 SkASSERT(s.fKind == ASTNode::Kind::kSwitch);
529 AutoSwitchLevel level(this);
530 auto iter = s.begin();
531 std::unique_ptr<Expression> value = this->convertExpression(*(iter++));
532 if (!value) {
533 return nullptr;
534 }
535 if (value->fType != *fContext.fUInt_Type && value->fType.kind() != Type::kEnum_Kind) {
536 value = this->coerce(std::move(value), *fContext.fInt_Type);
537 if (!value) {
538 return nullptr;
539 }
540 }
541 AutoSymbolTable table(this);
542 std::unordered_set<int> caseValues;
543 std::vector<std::unique_ptr<SwitchCase>> cases;
544 for (; iter != s.end(); ++iter) {
545 const ASTNode& c = *iter;
546 SkASSERT(c.fKind == ASTNode::Kind::kSwitchCase);
547 std::unique_ptr<Expression> caseValue;
548 auto childIter = c.begin();
549 if (*childIter) {
550 caseValue = this->convertExpression(*childIter);
551 if (!caseValue) {
552 return nullptr;
553 }
554 caseValue = this->coerce(std::move(caseValue), value->fType);
555 if (!caseValue) {
556 return nullptr;
557 }
558 if (!caseValue->isConstant()) {
559 fErrors.error(caseValue->fOffset, "case value must be a constant");
560 return nullptr;
561 }
562 int64_t v;
563 this->getConstantInt(*caseValue, &v);
564 if (caseValues.find(v) != caseValues.end()) {
565 fErrors.error(caseValue->fOffset, "duplicate case value");
566 }
567 caseValues.insert(v);
568 }
569 ++childIter;
570 std::vector<std::unique_ptr<Statement>> statements;
571 for (; childIter != c.end(); ++childIter) {
572 std::unique_ptr<Statement> converted = this->convertStatement(*childIter);
573 if (!converted) {
574 return nullptr;
575 }
576 statements.push_back(std::move(converted));
577 }
578 cases.emplace_back(new SwitchCase(c.fOffset, std::move(caseValue),
579 std::move(statements)));
580 }
581 return std::unique_ptr<Statement>(new SwitchStatement(s.fOffset, s.getBool(),
582 std::move(value), std::move(cases),
583 fSymbolTable));
584}
585
586std::unique_ptr<Statement> IRGenerator::convertExpressionStatement(const ASTNode& s) {
587 std::unique_ptr<Expression> e = this->convertExpression(s);
588 if (!e) {
589 return nullptr;
590 }
591 this->checkValid(*e);
592 return std::unique_ptr<Statement>(new ExpressionStatement(std::move(e)));
593}
594
595std::unique_ptr<Statement> IRGenerator::convertReturn(const ASTNode& r) {
596 SkASSERT(r.fKind == ASTNode::Kind::kReturn);
597 SkASSERT(fCurrentFunction);
598 // early returns from a vertex main function will bypass the sk_Position normalization, so
599 // SkASSERT that we aren't doing that. It is of course possible to fix this by adding a
600 // normalization before each return, but it will probably never actually be necessary.
601 SkASSERT(Program::kVertex_Kind != fKind || !fRTAdjust || "main" != fCurrentFunction->fName);
602 if (r.begin() != r.end()) {
603 std::unique_ptr<Expression> result = this->convertExpression(*r.begin());
604 if (!result) {
605 return nullptr;
606 }
607 if (fCurrentFunction->fReturnType == *fContext.fVoid_Type) {
608 fErrors.error(result->fOffset, "may not return a value from a void function");
609 } else {
610 result = this->coerce(std::move(result), fCurrentFunction->fReturnType);
611 if (!result) {
612 return nullptr;
613 }
614 }
615 return std::unique_ptr<Statement>(new ReturnStatement(std::move(result)));
616 } else {
617 if (fCurrentFunction->fReturnType != *fContext.fVoid_Type) {
618 fErrors.error(r.fOffset, "expected function to return '" +
619 fCurrentFunction->fReturnType.displayName() + "'");
620 }
621 return std::unique_ptr<Statement>(new ReturnStatement(r.fOffset));
622 }
623}
624
625std::unique_ptr<Statement> IRGenerator::convertBreak(const ASTNode& b) {
626 SkASSERT(b.fKind == ASTNode::Kind::kBreak);
627 if (fLoopLevel > 0 || fSwitchLevel > 0) {
628 return std::unique_ptr<Statement>(new BreakStatement(b.fOffset));
629 } else {
630 fErrors.error(b.fOffset, "break statement must be inside a loop or switch");
631 return nullptr;
632 }
633}
634
635std::unique_ptr<Statement> IRGenerator::convertContinue(const ASTNode& c) {
636 SkASSERT(c.fKind == ASTNode::Kind::kContinue);
637 if (fLoopLevel > 0) {
638 return std::unique_ptr<Statement>(new ContinueStatement(c.fOffset));
639 } else {
640 fErrors.error(c.fOffset, "continue statement must be inside a loop");
641 return nullptr;
642 }
643}
644
645std::unique_ptr<Statement> IRGenerator::convertDiscard(const ASTNode& d) {
646 SkASSERT(d.fKind == ASTNode::Kind::kDiscard);
647 return std::unique_ptr<Statement>(new DiscardStatement(d.fOffset));
648}
649
650std::unique_ptr<Block> IRGenerator::applyInvocationIDWorkaround(std::unique_ptr<Block> main) {
651 Layout invokeLayout;
652 Modifiers invokeModifiers(invokeLayout, Modifiers::kHasSideEffects_Flag);
653 FunctionDeclaration* invokeDecl = new FunctionDeclaration(-1,
654 invokeModifiers,
655 "_invoke",
656 std::vector<const Variable*>(),
657 *fContext.fVoid_Type);
658 fProgramElements->push_back(std::unique_ptr<ProgramElement>(
659 new FunctionDefinition(-1, *invokeDecl, std::move(main))));
660 fSymbolTable->add(invokeDecl->fName, std::unique_ptr<FunctionDeclaration>(invokeDecl));
661
662 std::vector<std::unique_ptr<VarDeclaration>> variables;
663 Variable* loopIdx = (Variable*) (*fSymbolTable)["sk_InvocationID"];
664 SkASSERT(loopIdx);
665 std::unique_ptr<Expression> test(new BinaryExpression(-1,
666 std::unique_ptr<Expression>(new VariableReference(-1, *loopIdx)),
667 Token::LT,
668 std::unique_ptr<IntLiteral>(new IntLiteral(fContext, -1, fInvocations)),
669 *fContext.fBool_Type));
670 std::unique_ptr<Expression> next(new PostfixExpression(
671 std::unique_ptr<Expression>(
672 new VariableReference(-1,
673 *loopIdx,
674 VariableReference::kReadWrite_RefKind)),
675 Token::PLUSPLUS));
676 ASTNode endPrimitiveID(&fFile->fNodes, -1, ASTNode::Kind::kIdentifier, "EndPrimitive");
677 std::unique_ptr<Expression> endPrimitive = this->convertExpression(endPrimitiveID);
678 SkASSERT(endPrimitive);
679
680 std::vector<std::unique_ptr<Statement>> loopBody;
681 std::vector<std::unique_ptr<Expression>> invokeArgs;
682 loopBody.push_back(std::unique_ptr<Statement>(new ExpressionStatement(
683 this->call(-1,
684 *invokeDecl,
685 std::vector<std::unique_ptr<Expression>>()))));
686 loopBody.push_back(std::unique_ptr<Statement>(new ExpressionStatement(
687 this->call(-1,
688 std::move(endPrimitive),
689 std::vector<std::unique_ptr<Expression>>()))));
690 std::unique_ptr<Expression> assignment(new BinaryExpression(-1,
691 std::unique_ptr<Expression>(new VariableReference(-1, *loopIdx)),
692 Token::EQ,
693 std::unique_ptr<IntLiteral>(new IntLiteral(fContext, -1, 0)),
694 *fContext.fInt_Type));
695 std::unique_ptr<Statement> initializer(new ExpressionStatement(std::move(assignment)));
696 std::unique_ptr<Statement> loop = std::unique_ptr<Statement>(
697 new ForStatement(-1,
698 std::move(initializer),
699 std::move(test),
700 std::move(next),
701 std::unique_ptr<Block>(new Block(-1, std::move(loopBody))),
702 fSymbolTable));
703 std::vector<std::unique_ptr<Statement>> children;
704 children.push_back(std::move(loop));
705 return std::unique_ptr<Block>(new Block(-1, std::move(children)));
706}
707
708std::unique_ptr<Statement> IRGenerator::getNormalizeSkPositionCode() {
709 // sk_Position = float4(sk_Position.xy * rtAdjust.xz + sk_Position.ww * rtAdjust.yw,
710 // 0,
711 // sk_Position.w);
712 SkASSERT(fSkPerVertex && fRTAdjust);
713 #define REF(var) std::unique_ptr<Expression>(\
714 new VariableReference(-1, *var, VariableReference::kRead_RefKind))
715 #define FIELD(var, idx) std::unique_ptr<Expression>(\
716 new FieldAccess(REF(var), idx, FieldAccess::kAnonymousInterfaceBlock_OwnerKind))
717 #define POS std::unique_ptr<Expression>(new FieldAccess(REF(fSkPerVertex), 0, \
718 FieldAccess::kAnonymousInterfaceBlock_OwnerKind))
719 #define ADJUST (fRTAdjustInterfaceBlock ? \
720 FIELD(fRTAdjustInterfaceBlock, fRTAdjustFieldIndex) : \
721 REF(fRTAdjust))
722 #define SWIZZLE(expr, ...) std::unique_ptr<Expression>(new Swizzle(fContext, expr, \
723 { __VA_ARGS__ }))
724 #define OP(left, op, right) std::unique_ptr<Expression>( \
725 new BinaryExpression(-1, left, op, right, \
726 *fContext.fFloat2_Type))
727 std::vector<std::unique_ptr<Expression>> children;
728 children.push_back(OP(OP(SWIZZLE(POS, 0, 1), Token::STAR, SWIZZLE(ADJUST, 0, 2)),
729 Token::PLUS,
730 OP(SWIZZLE(POS, 3, 3), Token::STAR, SWIZZLE(ADJUST, 1, 3))));
731 children.push_back(std::unique_ptr<Expression>(new FloatLiteral(fContext, -1, 0.0)));
732 children.push_back(SWIZZLE(POS, 3));
733 std::unique_ptr<Expression> result = OP(POS, Token::EQ,
734 std::unique_ptr<Expression>(new Constructor(-1,
735 *fContext.fFloat4_Type,
736 std::move(children))));
737 return std::unique_ptr<Statement>(new ExpressionStatement(std::move(result)));
738}
739
740void IRGenerator::convertFunction(const ASTNode& f) {
741 auto iter = f.begin();
742 const Type* returnType = this->convertType(*(iter++));
743 if (!returnType) {
744 return;
745 }
746 const ASTNode::FunctionData& fd = f.getFunctionData();
747 std::vector<const Variable*> parameters;
748 for (size_t i = 0; i < fd.fParameterCount; ++i) {
749 const ASTNode& param = *(iter++);
750 SkASSERT(param.fKind == ASTNode::Kind::kParameter);
751 ASTNode::ParameterData pd = param.getParameterData();
752 auto paramIter = param.begin();
753 const Type* type = this->convertType(*(paramIter++));
754 if (!type) {
755 return;
756 }
757 for (int j = (int) pd.fSizeCount; j >= 1; j--) {
758 int size = (param.begin() + j)->getInt();
759 String name = type->name() + "[" + to_string(size) + "]";
760 type = (Type*) fSymbolTable->takeOwnership(
761 std::unique_ptr<Symbol>(new Type(std::move(name),
762 Type::kArray_Kind,
763 *type,
764 size)));
765 }
766 StringFragment name = pd.fName;
767 Variable* var = (Variable*) fSymbolTable->takeOwnership(
768 std::unique_ptr<Symbol>(new Variable(param.fOffset,
769 pd.fModifiers,
770 name,
771 *type,
772 Variable::kParameter_Storage)));
773 parameters.push_back(var);
774 }
775
776 if (fd.fName == "main") {
777 switch (fKind) {
778 case Program::kPipelineStage_Kind: {
779 bool valid;
780 switch (parameters.size()) {
781 case 2:
782 valid = parameters[0]->fType == *fContext.fFloat2_Type &&
783 parameters[0]->fModifiers.fFlags == 0 &&
784 parameters[1]->fType == *fContext.fHalf4_Type &&
785 parameters[1]->fModifiers.fFlags == (Modifiers::kIn_Flag |
786 Modifiers::kOut_Flag);
787 break;
788 case 1:
789 valid = parameters[0]->fType == *fContext.fHalf4_Type &&
790 parameters[0]->fModifiers.fFlags == (Modifiers::kIn_Flag |
791 Modifiers::kOut_Flag);
792 break;
793 default:
794 valid = false;
795 }
796 if (!valid) {
797 fErrors.error(f.fOffset, "pipeline stage 'main' must be declared main(float2, "
798 "inout half4) or main(inout half4)");
799 return;
800 }
801 break;
802 }
803 case Program::kGeneric_Kind:
804 break;
805 default:
806 if (parameters.size()) {
807 fErrors.error(f.fOffset, "shader 'main' must have zero parameters");
808 }
809 }
810 }
811
812 // find existing declaration
813 const FunctionDeclaration* decl = nullptr;
814 auto entry = (*fSymbolTable)[fd.fName];
815 if (entry) {
816 std::vector<const FunctionDeclaration*> functions;
817 switch (entry->fKind) {
818 case Symbol::kUnresolvedFunction_Kind:
819 functions = ((UnresolvedFunction*) entry)->fFunctions;
820 break;
821 case Symbol::kFunctionDeclaration_Kind:
822 functions.push_back((FunctionDeclaration*) entry);
823 break;
824 default:
825 fErrors.error(f.fOffset, "symbol '" + fd.fName + "' was already defined");
826 return;
827 }
828 for (const auto& other : functions) {
829 SkASSERT(other->fName == fd.fName);
830 if (parameters.size() == other->fParameters.size()) {
831 bool match = true;
832 for (size_t i = 0; i < parameters.size(); i++) {
833 if (parameters[i]->fType != other->fParameters[i]->fType) {
834 match = false;
835 break;
836 }
837 }
838 if (match) {
839 if (*returnType != other->fReturnType) {
840 FunctionDeclaration newDecl(f.fOffset, fd.fModifiers, fd.fName, parameters,
841 *returnType);
842 fErrors.error(f.fOffset, "functions '" + newDecl.declaration() +
843 "' and '" + other->declaration() +
844 "' differ only in return type");
845 return;
846 }
847 decl = other;
848 for (size_t i = 0; i < parameters.size(); i++) {
849 if (parameters[i]->fModifiers != other->fParameters[i]->fModifiers) {
850 fErrors.error(f.fOffset, "modifiers on parameter " +
851 to_string((uint64_t) i + 1) +
852 " differ between declaration and "
853 "definition");
854 return;
855 }
856 }
857 if (other->fDefined && !other->fBuiltin) {
858 fErrors.error(f.fOffset, "duplicate definition of " +
859 other->declaration());
860 }
861 break;
862 }
863 }
864 }
865 }
866 if (!decl) {
867 // couldn't find an existing declaration
868 auto newDecl = std::unique_ptr<FunctionDeclaration>(new FunctionDeclaration(f.fOffset,
869 fd.fModifiers,
870 fd.fName,
871 parameters,
872 *returnType));
873 decl = newDecl.get();
874 fSymbolTable->add(decl->fName, std::move(newDecl));
875 }
876 if (iter != f.end()) {
877 // compile body
878 SkASSERT(!fCurrentFunction);
879 fCurrentFunction = decl;
880 decl->fDefined = true;
881 std::shared_ptr<SymbolTable> old = fSymbolTable;
882 AutoSymbolTable table(this);
883 if (fd.fName == "main" && fKind == Program::kPipelineStage_Kind) {
884 if (parameters.size() == 2) {
885 parameters[0]->fModifiers.fLayout.fBuiltin = SK_MAIN_COORDS_BUILTIN;
886 parameters[1]->fModifiers.fLayout.fBuiltin = SK_OUTCOLOR_BUILTIN;
887 } else {
888 SkASSERT(parameters.size() == 1);
889 parameters[0]->fModifiers.fLayout.fBuiltin = SK_OUTCOLOR_BUILTIN;
890 }
891 }
892 for (size_t i = 0; i < parameters.size(); i++) {
893 fSymbolTable->addWithoutOwnership(parameters[i]->fName, decl->fParameters[i]);
894 }
895 bool needInvocationIDWorkaround = fInvocations != -1 && fd.fName == "main" &&
896 fSettings->fCaps &&
897 !fSettings->fCaps->gsInvocationsSupport();
898 std::unique_ptr<Block> body = this->convertBlock(*iter);
899 fCurrentFunction = nullptr;
900 if (!body) {
901 return;
902 }
903 if (needInvocationIDWorkaround) {
904 body = this->applyInvocationIDWorkaround(std::move(body));
905 }
906 // conservatively assume all user-defined functions have side effects
907 ((Modifiers&) decl->fModifiers).fFlags |= Modifiers::kHasSideEffects_Flag;
908 if (Program::kVertex_Kind == fKind && fd.fName == "main" && fRTAdjust) {
909 body->fStatements.insert(body->fStatements.end(), this->getNormalizeSkPositionCode());
910 }
911 std::unique_ptr<FunctionDefinition> result(new FunctionDefinition(f.fOffset, *decl,
912 std::move(body)));
913 result->fSource = &f;
914 fProgramElements->push_back(std::move(result));
915 }
916}
917
918std::unique_ptr<InterfaceBlock> IRGenerator::convertInterfaceBlock(const ASTNode& intf) {
919 SkASSERT(intf.fKind == ASTNode::Kind::kInterfaceBlock);
920 ASTNode::InterfaceBlockData id = intf.getInterfaceBlockData();
921 std::shared_ptr<SymbolTable> old = fSymbolTable;
922 this->pushSymbolTable();
923 std::shared_ptr<SymbolTable> symbols = fSymbolTable;
924 std::vector<Type::Field> fields;
925 bool haveRuntimeArray = false;
926 bool foundRTAdjust = false;
927 auto iter = intf.begin();
928 for (size_t i = 0; i < id.fDeclarationCount; ++i) {
929 std::unique_ptr<VarDeclarations> decl = this->convertVarDeclarations(
930 *(iter++),
931 Variable::kInterfaceBlock_Storage);
932 if (!decl) {
933 return nullptr;
934 }
935 for (const auto& stmt : decl->fVars) {
936 VarDeclaration& vd = (VarDeclaration&) *stmt;
937 if (haveRuntimeArray) {
938 fErrors.error(decl->fOffset,
939 "only the last entry in an interface block may be a runtime-sized "
940 "array");
941 }
942 if (vd.fVar == fRTAdjust) {
943 foundRTAdjust = true;
944 SkASSERT(vd.fVar->fType == *fContext.fFloat4_Type);
945 fRTAdjustFieldIndex = fields.size();
946 }
947 fields.push_back(Type::Field(vd.fVar->fModifiers, vd.fVar->fName,
948 &vd.fVar->fType));
949 if (vd.fValue) {
950 fErrors.error(decl->fOffset,
951 "initializers are not permitted on interface block fields");
952 }
953 if (vd.fVar->fModifiers.fFlags & (Modifiers::kIn_Flag |
954 Modifiers::kOut_Flag |
955 Modifiers::kUniform_Flag |
956 Modifiers::kBuffer_Flag |
957 Modifiers::kConst_Flag)) {
958 fErrors.error(decl->fOffset,
959 "interface block fields may not have storage qualifiers");
960 }
961 if (vd.fVar->fType.kind() == Type::kArray_Kind &&
962 vd.fVar->fType.columns() == -1) {
963 haveRuntimeArray = true;
964 }
965 }
966 }
967 this->popSymbolTable();
968 Type* type = (Type*) old->takeOwnership(std::unique_ptr<Symbol>(new Type(intf.fOffset,
969 id.fTypeName,
970 fields)));
971 std::vector<std::unique_ptr<Expression>> sizes;
972 for (size_t i = 0; i < id.fSizeCount; ++i) {
973 const ASTNode& size = *(iter++);
974 if (size) {
975 std::unique_ptr<Expression> converted = this->convertExpression(size);
976 if (!converted) {
977 return nullptr;
978 }
979 String name = type->fName;
980 int64_t count;
981 if (converted->fKind == Expression::kIntLiteral_Kind) {
982 count = ((IntLiteral&) *converted).fValue;
983 if (count <= 0) {
984 fErrors.error(converted->fOffset, "array size must be positive");
985 return nullptr;
986 }
987 name += "[" + to_string(count) + "]";
988 } else {
989 fErrors.error(intf.fOffset, "array size must be specified");
990 return nullptr;
991 }
992 type = (Type*) symbols->takeOwnership(std::unique_ptr<Symbol>(
993 new Type(name,
994 Type::kArray_Kind,
995 *type,
996 (int) count)));
997 sizes.push_back(std::move(converted));
998 } else {
999 fErrors.error(intf.fOffset, "array size must be specified");
1000 return nullptr;
1001 }
1002 }
1003 Variable* var = (Variable*) old->takeOwnership(std::unique_ptr<Symbol>(
1004 new Variable(intf.fOffset,
1005 id.fModifiers,
1006 id.fInstanceName.fLength ? id.fInstanceName : id.fTypeName,
1007 *type,
1008 Variable::kGlobal_Storage)));
1009 if (foundRTAdjust) {
1010 fRTAdjustInterfaceBlock = var;
1011 }
1012 if (id.fInstanceName.fLength) {
1013 old->addWithoutOwnership(id.fInstanceName, var);
1014 } else {
1015 for (size_t i = 0; i < fields.size(); i++) {
1016 old->add(fields[i].fName, std::unique_ptr<Field>(new Field(intf.fOffset, *var,
1017 (int) i)));
1018 }
1019 }
1020 return std::unique_ptr<InterfaceBlock>(new InterfaceBlock(intf.fOffset,
1021 var,
1022 id.fTypeName,
1023 id.fInstanceName,
1024 std::move(sizes),
1025 symbols));
1026}
1027
1028void IRGenerator::getConstantInt(const Expression& value, int64_t* out) {
1029 switch (value.fKind) {
1030 case Expression::kIntLiteral_Kind:
1031 *out = ((const IntLiteral&) value).fValue;
1032 break;
1033 case Expression::kVariableReference_Kind: {
1034 const Variable& var = ((VariableReference&) value).fVariable;
1035 if ((var.fModifiers.fFlags & Modifiers::kConst_Flag) &&
1036 var.fInitialValue) {
1037 this->getConstantInt(*var.fInitialValue, out);
1038 }
1039 break;
1040 }
1041 default:
1042 fErrors.error(value.fOffset, "expected a constant int");
1043 }
1044}
1045
1046void IRGenerator::convertEnum(const ASTNode& e) {
1047 SkASSERT(e.fKind == ASTNode::Kind::kEnum);
1048 std::vector<Variable*> variables;
1049 int64_t currentValue = 0;
1050 Layout layout;
1051 ASTNode enumType(e.fNodes, e.fOffset, ASTNode::Kind::kType,
1052 ASTNode::TypeData(e.getString(), false, false));
1053 const Type* type = this->convertType(enumType);
1054 Modifiers modifiers(layout, Modifiers::kConst_Flag);
1055 std::shared_ptr<SymbolTable> symbols(new SymbolTable(fSymbolTable, &fErrors));
1056 fSymbolTable = symbols;
1057 for (auto iter = e.begin(); iter != e.end(); ++iter) {
1058 const ASTNode& child = *iter;
1059 SkASSERT(child.fKind == ASTNode::Kind::kEnumCase);
1060 std::unique_ptr<Expression> value;
1061 if (child.begin() != child.end()) {
1062 value = this->convertExpression(*child.begin());
1063 if (!value) {
1064 fSymbolTable = symbols->fParent;
1065 return;
1066 }
1067 this->getConstantInt(*value, &currentValue);
1068 }
1069 value = std::unique_ptr<Expression>(new IntLiteral(fContext, e.fOffset, currentValue));
1070 ++currentValue;
1071 auto var = std::unique_ptr<Variable>(new Variable(e.fOffset, modifiers, child.getString(),
1072 *type, Variable::kGlobal_Storage,
1073 value.get()));
1074 variables.push_back(var.get());
1075 symbols->add(child.getString(), std::move(var));
1076 symbols->takeOwnership(std::move(value));
1077 }
1078 fProgramElements->push_back(std::unique_ptr<ProgramElement>(new Enum(e.fOffset, e.getString(),
1079 symbols)));
1080 fSymbolTable = symbols->fParent;
1081}
1082
1083const Type* IRGenerator::convertType(const ASTNode& type) {
1084 ASTNode::TypeData td = type.getTypeData();
1085 const Symbol* result = (*fSymbolTable)[td.fName];
1086 if (result && result->fKind == Symbol::kType_Kind) {
1087 if (td.fIsNullable) {
1088 if (((Type&) *result) == *fContext.fFragmentProcessor_Type) {
1089 if (type.begin() != type.end()) {
1090 fErrors.error(type.fOffset, "type '" + td.fName + "' may not be used in "
1091 "an array");
1092 }
1093 result = fSymbolTable->takeOwnership(std::unique_ptr<Symbol>(
1094 new Type(String(result->fName) + "?",
1095 Type::kNullable_Kind,
1096 (const Type&) *result)));
1097 } else {
1098 fErrors.error(type.fOffset, "type '" + td.fName + "' may not be nullable");
1099 }
1100 }
1101 for (const auto& size : type) {
1102 String name(result->fName);
1103 name += "[";
1104 if (size) {
1105 name += to_string(size.getInt());
1106 }
1107 name += "]";
1108 result = (Type*) fSymbolTable->takeOwnership(std::unique_ptr<Symbol>(
1109 new Type(name,
1110 Type::kArray_Kind,
1111 (const Type&) *result,
1112 size ? size.getInt()
1113 : 0)));
1114 }
1115 return (const Type*) result;
1116 }
1117 fErrors.error(type.fOffset, "unknown type '" + td.fName + "'");
1118 return nullptr;
1119}
1120
1121std::unique_ptr<Expression> IRGenerator::convertExpression(const ASTNode& expr) {
1122 switch (expr.fKind) {
1123 case ASTNode::Kind::kBinary:
1124 return this->convertBinaryExpression(expr);
1125 case ASTNode::Kind::kBool:
1126 return std::unique_ptr<Expression>(new BoolLiteral(fContext, expr.fOffset,
1127 expr.getBool()));
1128 case ASTNode::Kind::kCall:
1129 return this->convertCallExpression(expr);
1130 case ASTNode::Kind::kField:
1131 return this->convertFieldExpression(expr);
1132 case ASTNode::Kind::kFloat:
1133 return std::unique_ptr<Expression>(new FloatLiteral(fContext, expr.fOffset,
1134 expr.getFloat()));
1135 case ASTNode::Kind::kIdentifier:
1136 return this->convertIdentifier(expr);
1137 case ASTNode::Kind::kIndex:
1138 return this->convertIndexExpression(expr);
1139 case ASTNode::Kind::kInt:
1140 return std::unique_ptr<Expression>(new IntLiteral(fContext, expr.fOffset,
1141 expr.getInt()));
1142 case ASTNode::Kind::kNull:
1143 return std::unique_ptr<Expression>(new NullLiteral(fContext, expr.fOffset));
1144 case ASTNode::Kind::kPostfix:
1145 return this->convertPostfixExpression(expr);
1146 case ASTNode::Kind::kPrefix:
1147 return this->convertPrefixExpression(expr);
1148 case ASTNode::Kind::kTernary:
1149 return this->convertTernaryExpression(expr);
1150 default:
1151#ifdef SK_DEBUG
1152 ABORT("unsupported expression: %s\n", expr.description().c_str());
1153#endif
1154 return nullptr;
1155 }
1156}
1157
1158std::unique_ptr<Expression> IRGenerator::convertIdentifier(const ASTNode& identifier) {
1159 SkASSERT(identifier.fKind == ASTNode::Kind::kIdentifier);
1160 const Symbol* result = (*fSymbolTable)[identifier.getString()];
1161 if (!result) {
1162 fErrors.error(identifier.fOffset, "unknown identifier '" + identifier.getString() + "'");
1163 return nullptr;
1164 }
1165 switch (result->fKind) {
1166 case Symbol::kFunctionDeclaration_Kind: {
1167 std::vector<const FunctionDeclaration*> f = {
1168 (const FunctionDeclaration*) result
1169 };
1170 return std::unique_ptr<FunctionReference>(new FunctionReference(fContext,
1171 identifier.fOffset,
1172 f));
1173 }
1174 case Symbol::kUnresolvedFunction_Kind: {
1175 const UnresolvedFunction* f = (const UnresolvedFunction*) result;
1176 return std::unique_ptr<FunctionReference>(new FunctionReference(fContext,
1177 identifier.fOffset,
1178 f->fFunctions));
1179 }
1180 case Symbol::kVariable_Kind: {
1181 const Variable* var = (const Variable*) result;
1182 switch (var->fModifiers.fLayout.fBuiltin) {
1183 case SK_WIDTH_BUILTIN:
1184 fInputs.fRTWidth = true;
1185 break;
1186 case SK_HEIGHT_BUILTIN:
1187 fInputs.fRTHeight = true;
1188 break;
1189#ifndef SKSL_STANDALONE
1190 case SK_FRAGCOORD_BUILTIN:
1191 fInputs.fFlipY = true;
1192 if (fSettings->fFlipY &&
1193 (!fSettings->fCaps ||
1194 !fSettings->fCaps->fragCoordConventionsExtensionString())) {
1195 fInputs.fRTHeight = true;
1196 }
1197#endif
1198 }
1199 if (fKind == Program::kFragmentProcessor_Kind &&
1200 (var->fModifiers.fFlags & Modifiers::kIn_Flag) &&
1201 !(var->fModifiers.fFlags & Modifiers::kUniform_Flag) &&
1202 !var->fModifiers.fLayout.fKey &&
1203 var->fModifiers.fLayout.fBuiltin == -1 &&
1204 var->fType.nonnullable() != *fContext.fFragmentProcessor_Type &&
1205 var->fType.kind() != Type::kSampler_Kind) {
1206 bool valid = false;
1207 for (const auto& decl : fFile->root()) {
1208 if (decl.fKind == ASTNode::Kind::kSection) {
1209 ASTNode::SectionData section = decl.getSectionData();
1210 if (section.fName == "setData") {
1211 valid = true;
1212 break;
1213 }
1214 }
1215 }
1216 if (!valid) {
1217 fErrors.error(identifier.fOffset, "'in' variable must be either 'uniform' or "
1218 "'layout(key)', or there must be a custom "
1219 "@setData function");
1220 }
1221 }
1222 // default to kRead_RefKind; this will be corrected later if the variable is written to
1223 return std::unique_ptr<VariableReference>(new VariableReference(
1224 identifier.fOffset,
1225 *var,
1226 VariableReference::kRead_RefKind));
1227 }
1228 case Symbol::kField_Kind: {
1229 const Field* field = (const Field*) result;
1230 VariableReference* base = new VariableReference(identifier.fOffset, field->fOwner,
1231 VariableReference::kRead_RefKind);
1232 return std::unique_ptr<Expression>(new FieldAccess(
1233 std::unique_ptr<Expression>(base),
1234 field->fFieldIndex,
1235 FieldAccess::kAnonymousInterfaceBlock_OwnerKind));
1236 }
1237 case Symbol::kType_Kind: {
1238 const Type* t = (const Type*) result;
1239 return std::unique_ptr<TypeReference>(new TypeReference(fContext, identifier.fOffset,
1240 *t));
1241 }
1242 case Symbol::kExternal_Kind: {
1243 ExternalValue* r = (ExternalValue*) result;
1244 return std::unique_ptr<ExternalValueReference>(
1245 new ExternalValueReference(identifier.fOffset, r));
1246 }
1247 default:
1248 ABORT("unsupported symbol type %d\n", result->fKind);
1249 }
1250}
1251
1252std::unique_ptr<Section> IRGenerator::convertSection(const ASTNode& s) {
1253 ASTNode::SectionData section = s.getSectionData();
1254 return std::unique_ptr<Section>(new Section(s.fOffset, section.fName, section.fArgument,
1255 section.fText));
1256}
1257
1258
1259std::unique_ptr<Expression> IRGenerator::coerce(std::unique_ptr<Expression> expr,
1260 const Type& type) {
1261 if (!expr) {
1262 return nullptr;
1263 }
1264 if (expr->fType == type) {
1265 return expr;
1266 }
1267 this->checkValid(*expr);
1268 if (expr->fType == *fContext.fInvalid_Type) {
1269 return nullptr;
1270 }
1271 if (expr->coercionCost(type) == INT_MAX) {
1272 fErrors.error(expr->fOffset, "expected '" + type.displayName() + "', but found '" +
1273 expr->fType.displayName() + "'");
1274 return nullptr;
1275 }
1276 if (type.kind() == Type::kScalar_Kind) {
1277 std::vector<std::unique_ptr<Expression>> args;
1278 args.push_back(std::move(expr));
1279 std::unique_ptr<Expression> ctor;
1280 if (type == *fContext.fFloatLiteral_Type) {
1281 ctor = this->convertIdentifier(ASTNode(&fFile->fNodes, -1, ASTNode::Kind::kIdentifier,
1282 "float"));
1283 } else if (type == *fContext.fIntLiteral_Type) {
1284 ctor = this->convertIdentifier(ASTNode(&fFile->fNodes, -1, ASTNode::Kind::kIdentifier,
1285 "int"));
1286 } else {
1287 ctor = this->convertIdentifier(ASTNode(&fFile->fNodes, -1, ASTNode::Kind::kIdentifier,
1288 type.fName));
1289 }
1290 if (!ctor) {
1291 printf("error, null identifier: %s\n", String(type.fName).c_str());
1292 }
1293 SkASSERT(ctor);
1294 return this->call(-1, std::move(ctor), std::move(args));
1295 }
1296 if (expr->fKind == Expression::kNullLiteral_Kind) {
1297 SkASSERT(type.kind() == Type::kNullable_Kind);
1298 return std::unique_ptr<Expression>(new NullLiteral(expr->fOffset, type));
1299 }
1300 std::vector<std::unique_ptr<Expression>> args;
1301 args.push_back(std::move(expr));
1302 return std::unique_ptr<Expression>(new Constructor(-1, type, std::move(args)));
1303}
1304
1305static bool is_matrix_multiply(const Type& left, const Type& right) {
1306 if (left.kind() == Type::kMatrix_Kind) {
1307 return right.kind() == Type::kMatrix_Kind || right.kind() == Type::kVector_Kind;
1308 }
1309 return left.kind() == Type::kVector_Kind && right.kind() == Type::kMatrix_Kind;
1310}
1311
1312/**
1313 * Determines the operand and result types of a binary expression. Returns true if the expression is
1314 * legal, false otherwise. If false, the values of the out parameters are undefined.
1315 */
1316static bool determine_binary_type(const Context& context,
1317 Token::Kind op,
1318 const Type& left,
1319 const Type& right,
1320 const Type** outLeftType,
1321 const Type** outRightType,
1322 const Type** outResultType,
1323 bool tryFlipped) {
1324 bool isLogical;
1325 bool validMatrixOrVectorOp;
1326 switch (op) {
1327 case Token::EQ:
1328 *outLeftType = &left;
1329 *outRightType = &left;
1330 *outResultType = &left;
1331 return right.canCoerceTo(left);
1332 case Token::EQEQ: // fall through
1333 case Token::NEQ:
1334 if (right.canCoerceTo(left)) {
1335 *outLeftType = &left;
1336 *outRightType = &left;
1337 *outResultType = context.fBool_Type.get();
1338 return true;
1339 } if (left.canCoerceTo(right)) {
1340 *outLeftType = &right;
1341 *outRightType = &right;
1342 *outResultType = context.fBool_Type.get();
1343 return true;
1344 }
1345 return false;
1346 case Token::LT: // fall through
1347 case Token::GT: // fall through
1348 case Token::LTEQ: // fall through
1349 case Token::GTEQ:
1350 isLogical = true;
1351 validMatrixOrVectorOp = false;
1352 break;
1353 case Token::LOGICALOR: // fall through
1354 case Token::LOGICALAND: // fall through
1355 case Token::LOGICALXOR: // fall through
1356 case Token::LOGICALOREQ: // fall through
1357 case Token::LOGICALANDEQ: // fall through
1358 case Token::LOGICALXOREQ:
1359 *outLeftType = context.fBool_Type.get();
1360 *outRightType = context.fBool_Type.get();
1361 *outResultType = context.fBool_Type.get();
1362 return left.canCoerceTo(*context.fBool_Type) &&
1363 right.canCoerceTo(*context.fBool_Type);
1364 case Token::STAREQ:
1365 if (left.kind() == Type::kScalar_Kind) {
1366 *outLeftType = &left;
1367 *outRightType = &left;
1368 *outResultType = &left;
1369 return right.canCoerceTo(left);
1370 }
1371 // fall through
1372 case Token::STAR:
1373 if (is_matrix_multiply(left, right)) {
1374 // determine final component type
1375 if (determine_binary_type(context, Token::STAR, left.componentType(),
1376 right.componentType(), outLeftType, outRightType,
1377 outResultType, false)) {
1378 *outLeftType = &(*outResultType)->toCompound(context, left.columns(),
1379 left.rows());
1380 *outRightType = &(*outResultType)->toCompound(context, right.columns(),
1381 right.rows());
1382 int leftColumns = left.columns();
1383 int leftRows = left.rows();
1384 int rightColumns;
1385 int rightRows;
1386 if (right.kind() == Type::kVector_Kind) {
1387 // matrix * vector treats the vector as a column vector, so we need to
1388 // transpose it
1389 rightColumns = right.rows();
1390 rightRows = right.columns();
1391 SkASSERT(rightColumns == 1);
1392 } else {
1393 rightColumns = right.columns();
1394 rightRows = right.rows();
1395 }
1396 if (rightColumns > 1) {
1397 *outResultType = &(*outResultType)->toCompound(context, rightColumns,
1398 leftRows);
1399 } else {
1400 // result was a column vector, transpose it back to a row
1401 *outResultType = &(*outResultType)->toCompound(context, leftRows,
1402 rightColumns);
1403 }
1404 return leftColumns == rightRows;
1405 } else {
1406 return false;
1407 }
1408 }
1409 isLogical = false;
1410 validMatrixOrVectorOp = true;
1411 break;
1412 case Token::PLUSEQ:
1413 case Token::MINUSEQ:
1414 case Token::SLASHEQ:
1415 case Token::PERCENTEQ:
1416 case Token::SHLEQ:
1417 case Token::SHREQ:
1418 if (left.kind() == Type::kScalar_Kind) {
1419 *outLeftType = &left;
1420 *outRightType = &left;
1421 *outResultType = &left;
1422 return right.canCoerceTo(left);
1423 }
1424 // fall through
1425 case Token::PLUS: // fall through
1426 case Token::MINUS: // fall through
1427 case Token::SLASH: // fall through
1428 isLogical = false;
1429 validMatrixOrVectorOp = true;
1430 break;
1431 case Token::COMMA:
1432 *outLeftType = &left;
1433 *outRightType = &right;
1434 *outResultType = &right;
1435 return true;
1436 default:
1437 isLogical = false;
1438 validMatrixOrVectorOp = false;
1439 }
1440 bool isVectorOrMatrix = left.kind() == Type::kVector_Kind || left.kind() == Type::kMatrix_Kind;
1441 if (left.kind() == Type::kScalar_Kind && right.kind() == Type::kScalar_Kind &&
1442 right.canCoerceTo(left)) {
1443 if (left.priority() > right.priority()) {
1444 *outLeftType = &left;
1445 *outRightType = &left;
1446 } else {
1447 *outLeftType = &right;
1448 *outRightType = &right;
1449 }
1450 if (isLogical) {
1451 *outResultType = context.fBool_Type.get();
1452 } else {
1453 *outResultType = &left;
1454 }
1455 return true;
1456 }
1457 if (right.canCoerceTo(left) && isVectorOrMatrix && validMatrixOrVectorOp) {
1458 *outLeftType = &left;
1459 *outRightType = &left;
1460 if (isLogical) {
1461 *outResultType = context.fBool_Type.get();
1462 } else {
1463 *outResultType = &left;
1464 }
1465 return true;
1466 }
1467 if ((left.kind() == Type::kVector_Kind || left.kind() == Type::kMatrix_Kind) &&
1468 (right.kind() == Type::kScalar_Kind)) {
1469 if (determine_binary_type(context, op, left.componentType(), right, outLeftType,
1470 outRightType, outResultType, false)) {
1471 *outLeftType = &(*outLeftType)->toCompound(context, left.columns(), left.rows());
1472 if (!isLogical) {
1473 *outResultType = &(*outResultType)->toCompound(context, left.columns(),
1474 left.rows());
1475 }
1476 return true;
1477 }
1478 return false;
1479 }
1480 if (tryFlipped) {
1481 return determine_binary_type(context, op, right, left, outRightType, outLeftType,
1482 outResultType, false);
1483 }
1484 return false;
1485}
1486
1487static std::unique_ptr<Expression> short_circuit_boolean(const Context& context,
1488 const Expression& left,
1489 Token::Kind op,
1490 const Expression& right) {
1491 SkASSERT(left.fKind == Expression::kBoolLiteral_Kind);
1492 bool leftVal = ((BoolLiteral&) left).fValue;
1493 if (op == Token::LOGICALAND) {
1494 // (true && expr) -> (expr) and (false && expr) -> (false)
1495 return leftVal ? right.clone()
1496 : std::unique_ptr<Expression>(new BoolLiteral(context, left.fOffset, false));
1497 } else if (op == Token::LOGICALOR) {
1498 // (true || expr) -> (true) and (false || expr) -> (expr)
1499 return leftVal ? std::unique_ptr<Expression>(new BoolLiteral(context, left.fOffset, true))
1500 : right.clone();
1501 } else if (op == Token::LOGICALXOR) {
1502 // (true ^^ expr) -> !(expr) and (false ^^ expr) -> (expr)
1503 return leftVal ? std::unique_ptr<Expression>(new PrefixExpression(Token::LOGICALNOT,
1504 right.clone()))
1505 : right.clone();
1506 } else {
1507 return nullptr;
1508 }
1509}
1510
1511std::unique_ptr<Expression> IRGenerator::constantFold(const Expression& left,
1512 Token::Kind op,
1513 const Expression& right) const {
1514 // If the left side is a constant boolean literal, the right side does not need to be constant
1515 // for short circuit optimizations to allow the constant to be folded.
1516 if (left.fKind == Expression::kBoolLiteral_Kind && !right.isConstant()) {
1517 return short_circuit_boolean(fContext, left, op, right);
1518 } else if (right.fKind == Expression::kBoolLiteral_Kind && !left.isConstant()) {
1519 // There aren't side effects in SKSL within expressions, so (left OP right) is equivalent to
1520 // (right OP left) for short-circuit optimizations
1521 return short_circuit_boolean(fContext, right, op, left);
1522 }
1523
1524 // Other than the short-circuit cases above, constant folding requires both sides to be constant
1525 if (!left.isConstant() || !right.isConstant()) {
1526 return nullptr;
1527 }
1528 // Note that we expressly do not worry about precision and overflow here -- we use the maximum
1529 // precision to calculate the results and hope the result makes sense. The plan is to move the
1530 // Skia caps into SkSL, so we have access to all of them including the precisions of the various
1531 // types, which will let us be more intelligent about this.
1532 if (left.fKind == Expression::kBoolLiteral_Kind &&
1533 right.fKind == Expression::kBoolLiteral_Kind) {
1534 bool leftVal = ((BoolLiteral&) left).fValue;
1535 bool rightVal = ((BoolLiteral&) right).fValue;
1536 bool result;
1537 switch (op) {
1538 case Token::LOGICALAND: result = leftVal && rightVal; break;
1539 case Token::LOGICALOR: result = leftVal || rightVal; break;
1540 case Token::LOGICALXOR: result = leftVal ^ rightVal; break;
1541 default: return nullptr;
1542 }
1543 return std::unique_ptr<Expression>(new BoolLiteral(fContext, left.fOffset, result));
1544 }
1545 #define RESULT(t, op) std::unique_ptr<Expression>(new t ## Literal(fContext, left.fOffset, \
1546 leftVal op rightVal))
1547 if (left.fKind == Expression::kIntLiteral_Kind && right.fKind == Expression::kIntLiteral_Kind) {
1548 int64_t leftVal = ((IntLiteral&) left).fValue;
1549 int64_t rightVal = ((IntLiteral&) right).fValue;
1550 switch (op) {
1551 case Token::PLUS: return RESULT(Int, +);
1552 case Token::MINUS: return RESULT(Int, -);
1553 case Token::STAR: return RESULT(Int, *);
1554 case Token::SLASH:
1555 if (rightVal) {
1556 return RESULT(Int, /);
1557 }
1558 fErrors.error(right.fOffset, "division by zero");
1559 return nullptr;
1560 case Token::PERCENT:
1561 if (rightVal) {
1562 return RESULT(Int, %);
1563 }
1564 fErrors.error(right.fOffset, "division by zero");
1565 return nullptr;
1566 case Token::BITWISEAND: return RESULT(Int, &);
1567 case Token::BITWISEOR: return RESULT(Int, |);
1568 case Token::BITWISEXOR: return RESULT(Int, ^);
1569 case Token::EQEQ: return RESULT(Bool, ==);
1570 case Token::NEQ: return RESULT(Bool, !=);
1571 case Token::GT: return RESULT(Bool, >);
1572 case Token::GTEQ: return RESULT(Bool, >=);
1573 case Token::LT: return RESULT(Bool, <);
1574 case Token::LTEQ: return RESULT(Bool, <=);
1575 case Token::SHL:
1576 if (rightVal >= 0 && rightVal <= 31) {
1577 return RESULT(Int, <<);
1578 }
1579 fErrors.error(right.fOffset, "shift value out of range");
1580 return nullptr;
1581 case Token::SHR:
1582 if (rightVal >= 0 && rightVal <= 31) {
1583 return RESULT(Int, >>);
1584 }
1585 fErrors.error(right.fOffset, "shift value out of range");
1586 return nullptr;
1587
1588 default:
1589 return nullptr;
1590 }
1591 }
1592 if (left.fKind == Expression::kFloatLiteral_Kind &&
1593 right.fKind == Expression::kFloatLiteral_Kind) {
1594 double leftVal = ((FloatLiteral&) left).fValue;
1595 double rightVal = ((FloatLiteral&) right).fValue;
1596 switch (op) {
1597 case Token::PLUS: return RESULT(Float, +);
1598 case Token::MINUS: return RESULT(Float, -);
1599 case Token::STAR: return RESULT(Float, *);
1600 case Token::SLASH:
1601 if (rightVal) {
1602 return RESULT(Float, /);
1603 }
1604 fErrors.error(right.fOffset, "division by zero");
1605 return nullptr;
1606 case Token::EQEQ: return RESULT(Bool, ==);
1607 case Token::NEQ: return RESULT(Bool, !=);
1608 case Token::GT: return RESULT(Bool, >);
1609 case Token::GTEQ: return RESULT(Bool, >=);
1610 case Token::LT: return RESULT(Bool, <);
1611 case Token::LTEQ: return RESULT(Bool, <=);
1612 default: return nullptr;
1613 }
1614 }
1615 if (left.fType.kind() == Type::kVector_Kind && left.fType.componentType().isFloat() &&
1616 left.fType == right.fType) {
1617 std::vector<std::unique_ptr<Expression>> args;
1618 #define RETURN_VEC_COMPONENTWISE_RESULT(op) \
1619 for (int i = 0; i < left.fType.columns(); i++) { \
1620 float value = left.getFVecComponent(i) op \
1621 right.getFVecComponent(i); \
1622 args.emplace_back(new FloatLiteral(fContext, -1, value)); \
1623 } \
1624 return std::unique_ptr<Expression>(new Constructor(-1, left.fType, \
1625 std::move(args)))
1626 switch (op) {
1627 case Token::EQEQ:
1628 return std::unique_ptr<Expression>(new BoolLiteral(fContext, -1,
1629 left.compareConstant(fContext, right)));
1630 case Token::NEQ:
1631 return std::unique_ptr<Expression>(new BoolLiteral(fContext, -1,
1632 !left.compareConstant(fContext, right)));
1633 case Token::PLUS: RETURN_VEC_COMPONENTWISE_RESULT(+);
1634 case Token::MINUS: RETURN_VEC_COMPONENTWISE_RESULT(-);
1635 case Token::STAR: RETURN_VEC_COMPONENTWISE_RESULT(*);
1636 case Token::SLASH:
1637 for (int i = 0; i < left.fType.columns(); i++) {
1638 SKSL_FLOAT rvalue = right.getFVecComponent(i);
1639 if (rvalue == 0.0) {
1640 fErrors.error(right.fOffset, "division by zero");
1641 return nullptr;
1642 }
1643 float value = left.getFVecComponent(i) / rvalue;
1644 args.emplace_back(new FloatLiteral(fContext, -1, value));
1645 }
1646 return std::unique_ptr<Expression>(new Constructor(-1, left.fType,
1647 std::move(args)));
1648 default: return nullptr;
1649 }
1650 }
1651 if (left.fType.kind() == Type::kMatrix_Kind &&
1652 right.fType.kind() == Type::kMatrix_Kind &&
1653 left.fKind == right.fKind) {
1654 switch (op) {
1655 case Token::EQEQ:
1656 return std::unique_ptr<Expression>(new BoolLiteral(fContext, -1,
1657 left.compareConstant(fContext, right)));
1658 case Token::NEQ:
1659 return std::unique_ptr<Expression>(new BoolLiteral(fContext, -1,
1660 !left.compareConstant(fContext, right)));
1661 default:
1662 return nullptr;
1663 }
1664 }
1665 #undef RESULT
1666 return nullptr;
1667}
1668
1669std::unique_ptr<Expression> IRGenerator::convertBinaryExpression(const ASTNode& expression) {
1670 SkASSERT(expression.fKind == ASTNode::Kind::kBinary);
1671 auto iter = expression.begin();
1672 std::unique_ptr<Expression> left = this->convertExpression(*(iter++));
1673 if (!left) {
1674 return nullptr;
1675 }
1676 std::unique_ptr<Expression> right = this->convertExpression(*(iter++));
1677 if (!right) {
1678 return nullptr;
1679 }
1680 const Type* leftType;
1681 const Type* rightType;
1682 const Type* resultType;
1683 const Type* rawLeftType;
1684 if (left->fKind == Expression::kIntLiteral_Kind && right->fType.isInteger()) {
1685 rawLeftType = &right->fType;
1686 } else {
1687 rawLeftType = &left->fType;
1688 }
1689 const Type* rawRightType;
1690 if (right->fKind == Expression::kIntLiteral_Kind && left->fType.isInteger()) {
1691 rawRightType = &left->fType;
1692 } else {
1693 rawRightType = &right->fType;
1694 }
1695 Token::Kind op = expression.getToken().fKind;
1696 if (!determine_binary_type(fContext, op, *rawLeftType, *rawRightType, &leftType, &rightType,
1697 &resultType, !Compiler::IsAssignment(op))) {
1698 fErrors.error(expression.fOffset, String("type mismatch: '") +
1699 Compiler::OperatorName(expression.getToken().fKind) +
1700 "' cannot operate on '" + left->fType.displayName() +
1701 "', '" + right->fType.displayName() + "'");
1702 return nullptr;
1703 }
1704 if (Compiler::IsAssignment(op)) {
1705 this->setRefKind(*left, op != Token::EQ ? VariableReference::kReadWrite_RefKind :
1706 VariableReference::kWrite_RefKind);
1707 }
1708 left = this->coerce(std::move(left), *leftType);
1709 right = this->coerce(std::move(right), *rightType);
1710 if (!left || !right) {
1711 return nullptr;
1712 }
1713 std::unique_ptr<Expression> result = this->constantFold(*left.get(), op, *right.get());
1714 if (!result) {
1715 result = std::unique_ptr<Expression>(new BinaryExpression(expression.fOffset,
1716 std::move(left),
1717 op,
1718 std::move(right),
1719 *resultType));
1720 }
1721 return result;
1722}
1723
1724std::unique_ptr<Expression> IRGenerator::convertTernaryExpression(const ASTNode& node) {
1725 SkASSERT(node.fKind == ASTNode::Kind::kTernary);
1726 auto iter = node.begin();
1727 std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*(iter++)),
1728 *fContext.fBool_Type);
1729 if (!test) {
1730 return nullptr;
1731 }
1732 std::unique_ptr<Expression> ifTrue = this->convertExpression(*(iter++));
1733 if (!ifTrue) {
1734 return nullptr;
1735 }
1736 std::unique_ptr<Expression> ifFalse = this->convertExpression(*(iter++));
1737 if (!ifFalse) {
1738 return nullptr;
1739 }
1740 const Type* trueType;
1741 const Type* falseType;
1742 const Type* resultType;
1743 if (!determine_binary_type(fContext, Token::EQEQ, ifTrue->fType, ifFalse->fType, &trueType,
1744 &falseType, &resultType, true) || trueType != falseType) {
1745 fErrors.error(node.fOffset, "ternary operator result mismatch: '" +
1746 ifTrue->fType.displayName() + "', '" +
1747 ifFalse->fType.displayName() + "'");
1748 return nullptr;
1749 }
1750 ifTrue = this->coerce(std::move(ifTrue), *trueType);
1751 if (!ifTrue) {
1752 return nullptr;
1753 }
1754 ifFalse = this->coerce(std::move(ifFalse), *falseType);
1755 if (!ifFalse) {
1756 return nullptr;
1757 }
1758 if (test->fKind == Expression::kBoolLiteral_Kind) {
1759 // static boolean test, just return one of the branches
1760 if (((BoolLiteral&) *test).fValue) {
1761 return ifTrue;
1762 } else {
1763 return ifFalse;
1764 }
1765 }
1766 return std::unique_ptr<Expression>(new TernaryExpression(node.fOffset,
1767 std::move(test),
1768 std::move(ifTrue),
1769 std::move(ifFalse)));
1770}
1771
1772std::unique_ptr<Expression> IRGenerator::call(int offset,
1773 const FunctionDeclaration& function,
1774 std::vector<std::unique_ptr<Expression>> arguments) {
1775 if (function.fBuiltin) {
1776 auto found = fIntrinsics->find(function.fName);
1777 if (found != fIntrinsics->end() && !found->second.second) {
1778 found->second.second = true;
1779 const FunctionDeclaration* old = fCurrentFunction;
1780 fCurrentFunction = nullptr;
1781 this->convertFunction(*((FunctionDefinition&) *found->second.first).fSource);
1782 fCurrentFunction = old;
1783 }
1784 }
1785 if (function.fParameters.size() != arguments.size()) {
1786 String msg = "call to '" + function.fName + "' expected " +
1787 to_string((uint64_t) function.fParameters.size()) +
1788 " argument";
1789 if (function.fParameters.size() != 1) {
1790 msg += "s";
1791 }
1792 msg += ", but found " + to_string((uint64_t) arguments.size());
1793 fErrors.error(offset, msg);
1794 return nullptr;
1795 }
1796 if (fKind == Program::kPipelineStage_Kind && !function.fDefined && !function.fBuiltin) {
1797 String msg = "call to undefined function '" + function.fName + "'";
1798 fErrors.error(offset, msg);
1799 return nullptr;
1800 }
1801 std::vector<const Type*> types;
1802 const Type* returnType;
1803 if (!function.determineFinalTypes(arguments, &types, &returnType)) {
1804 String msg = "no match for " + function.fName + "(";
1805 String separator;
1806 for (size_t i = 0; i < arguments.size(); i++) {
1807 msg += separator;
1808 separator = ", ";
1809 msg += arguments[i]->fType.displayName();
1810 }
1811 msg += ")";
1812 fErrors.error(offset, msg);
1813 return nullptr;
1814 }
1815 for (size_t i = 0; i < arguments.size(); i++) {
1816 arguments[i] = this->coerce(std::move(arguments[i]), *types[i]);
1817 if (!arguments[i]) {
1818 return nullptr;
1819 }
1820 if (arguments[i] && (function.fParameters[i]->fModifiers.fFlags & Modifiers::kOut_Flag)) {
1821 this->setRefKind(*arguments[i],
1822 function.fParameters[i]->fModifiers.fFlags & Modifiers::kIn_Flag ?
1823 VariableReference::kReadWrite_RefKind :
1824 VariableReference::kPointer_RefKind);
1825 }
1826 }
1827 return std::unique_ptr<FunctionCall>(new FunctionCall(offset, *returnType, function,
1828 std::move(arguments)));
1829}
1830
1831/**
1832 * Determines the cost of coercing the arguments of a function to the required types. Cost has no
1833 * particular meaning other than "lower costs are preferred". Returns INT_MAX if the call is not
1834 * valid.
1835 */
1836int IRGenerator::callCost(const FunctionDeclaration& function,
1837 const std::vector<std::unique_ptr<Expression>>& arguments) {
1838 if (function.fParameters.size() != arguments.size()) {
1839 return INT_MAX;
1840 }
1841 int total = 0;
1842 std::vector<const Type*> types;
1843 const Type* ignored;
1844 if (!function.determineFinalTypes(arguments, &types, &ignored)) {
1845 return INT_MAX;
1846 }
1847 for (size_t i = 0; i < arguments.size(); i++) {
1848 int cost = arguments[i]->coercionCost(*types[i]);
1849 if (cost != INT_MAX) {
1850 total += cost;
1851 } else {
1852 return INT_MAX;
1853 }
1854 }
1855 return total;
1856}
1857
1858std::unique_ptr<Expression> IRGenerator::call(int offset,
1859 std::unique_ptr<Expression> functionValue,
1860 std::vector<std::unique_ptr<Expression>> arguments) {
1861 switch (functionValue->fKind) {
1862 case Expression::kTypeReference_Kind:
1863 return this->convertConstructor(offset,
1864 ((TypeReference&) *functionValue).fValue,
1865 std::move(arguments));
1866 case Expression::kExternalValue_Kind: {
1867 ExternalValue* v = ((ExternalValueReference&) *functionValue).fValue;
1868 if (!v->canCall()) {
1869 fErrors.error(offset, "this external value is not a function");
1870 return nullptr;
1871 }
1872 int count = v->callParameterCount();
1873 if (count != (int) arguments.size()) {
1874 fErrors.error(offset, "external function expected " + to_string(count) +
1875 " arguments, but found " + to_string((int) arguments.size()));
1876 return nullptr;
1877 }
1878 static constexpr int PARAMETER_MAX = 16;
1879 SkASSERT(count < PARAMETER_MAX);
1880 const Type* types[PARAMETER_MAX];
1881 v->getCallParameterTypes(types);
1882 for (int i = 0; i < count; ++i) {
1883 arguments[i] = this->coerce(std::move(arguments[i]), *types[i]);
1884 if (!arguments[i]) {
1885 return nullptr;
1886 }
1887 }
1888 return std::unique_ptr<Expression>(new ExternalFunctionCall(offset, v->callReturnType(),
1889 v, std::move(arguments)));
1890 }
1891 case Expression::kFunctionReference_Kind: {
1892 FunctionReference* ref = (FunctionReference*) functionValue.get();
1893 int bestCost = INT_MAX;
1894 const FunctionDeclaration* best = nullptr;
1895 if (ref->fFunctions.size() > 1) {
1896 for (const auto& f : ref->fFunctions) {
1897 int cost = this->callCost(*f, arguments);
1898 if (cost < bestCost) {
1899 bestCost = cost;
1900 best = f;
1901 }
1902 }
1903 if (best) {
1904 return this->call(offset, *best, std::move(arguments));
1905 }
1906 String msg = "no match for " + ref->fFunctions[0]->fName + "(";
1907 String separator;
1908 for (size_t i = 0; i < arguments.size(); i++) {
1909 msg += separator;
1910 separator = ", ";
1911 msg += arguments[i]->fType.displayName();
1912 }
1913 msg += ")";
1914 fErrors.error(offset, msg);
1915 return nullptr;
1916 }
1917 return this->call(offset, *ref->fFunctions[0], std::move(arguments));
1918 }
1919 default:
1920 fErrors.error(offset, "not a function");
1921 return nullptr;
1922 }
1923}
1924
1925std::unique_ptr<Expression> IRGenerator::convertNumberConstructor(
1926 int offset,
1927 const Type& type,
1928 std::vector<std::unique_ptr<Expression>> args) {
1929 SkASSERT(type.isNumber());
1930 if (args.size() != 1) {
1931 fErrors.error(offset, "invalid arguments to '" + type.displayName() +
1932 "' constructor, (expected exactly 1 argument, but found " +
1933 to_string((uint64_t) args.size()) + ")");
1934 return nullptr;
1935 }
1936 if (type == args[0]->fType) {
1937 return std::move(args[0]);
1938 }
1939 if (type.isFloat() && args.size() == 1 && args[0]->fKind == Expression::kFloatLiteral_Kind) {
1940 double value = ((FloatLiteral&) *args[0]).fValue;
1941 return std::unique_ptr<Expression>(new FloatLiteral(offset, value, &type));
1942 }
1943 if (type.isFloat() && args.size() == 1 && args[0]->fKind == Expression::kIntLiteral_Kind) {
1944 int64_t value = ((IntLiteral&) *args[0]).fValue;
1945 return std::unique_ptr<Expression>(new FloatLiteral(offset, (double) value, &type));
1946 }
1947 if (args[0]->fKind == Expression::kIntLiteral_Kind && (type == *fContext.fInt_Type ||
1948 type == *fContext.fUInt_Type)) {
1949 return std::unique_ptr<Expression>(new IntLiteral(offset,
1950 ((IntLiteral&) *args[0]).fValue,
1951 &type));
1952 }
1953 if (args[0]->fType == *fContext.fBool_Type) {
1954 std::unique_ptr<IntLiteral> zero(new IntLiteral(fContext, offset, 0));
1955 std::unique_ptr<IntLiteral> one(new IntLiteral(fContext, offset, 1));
1956 return std::unique_ptr<Expression>(
1957 new TernaryExpression(offset, std::move(args[0]),
1958 this->coerce(std::move(one), type),
1959 this->coerce(std::move(zero),
1960 type)));
1961 }
1962 if (!args[0]->fType.isNumber()) {
1963 fErrors.error(offset, "invalid argument to '" + type.displayName() +
1964 "' constructor (expected a number or bool, but found '" +
1965 args[0]->fType.displayName() + "')");
1966 return nullptr;
1967 }
1968 return std::unique_ptr<Expression>(new Constructor(offset, type, std::move(args)));
1969}
1970
1971int component_count(const Type& type) {
1972 switch (type.kind()) {
1973 case Type::kVector_Kind:
1974 return type.columns();
1975 case Type::kMatrix_Kind:
1976 return type.columns() * type.rows();
1977 default:
1978 return 1;
1979 }
1980}
1981
1982std::unique_ptr<Expression> IRGenerator::convertCompoundConstructor(
1983 int offset,
1984 const Type& type,
1985 std::vector<std::unique_ptr<Expression>> args) {
1986 SkASSERT(type.kind() == Type::kVector_Kind || type.kind() == Type::kMatrix_Kind);
1987 if (type.kind() == Type::kMatrix_Kind && args.size() == 1 &&
1988 args[0]->fType.kind() == Type::kMatrix_Kind) {
1989 // matrix from matrix is always legal
1990 return std::unique_ptr<Expression>(new Constructor(offset, type, std::move(args)));
1991 }
1992 int actual = 0;
1993 int expected = type.rows() * type.columns();
1994 if (args.size() != 1 || expected != component_count(args[0]->fType) ||
1995 type.componentType().isNumber() != args[0]->fType.componentType().isNumber()) {
1996 for (size_t i = 0; i < args.size(); i++) {
1997 if (args[i]->fType.kind() == Type::kVector_Kind) {
1998 if (type.componentType().isNumber() !=
1999 args[i]->fType.componentType().isNumber()) {
2000 fErrors.error(offset, "'" + args[i]->fType.displayName() + "' is not a valid "
2001 "parameter to '" + type.displayName() +
2002 "' constructor");
2003 return nullptr;
2004 }
2005 actual += args[i]->fType.columns();
2006 } else if (args[i]->fType.kind() == Type::kScalar_Kind) {
2007 actual += 1;
2008 if (type.kind() != Type::kScalar_Kind) {
2009 args[i] = this->coerce(std::move(args[i]), type.componentType());
2010 if (!args[i]) {
2011 return nullptr;
2012 }
2013 }
2014 } else {
2015 fErrors.error(offset, "'" + args[i]->fType.displayName() + "' is not a valid "
2016 "parameter to '" + type.displayName() + "' constructor");
2017 return nullptr;
2018 }
2019 }
2020 if (actual != 1 && actual != expected) {
2021 fErrors.error(offset, "invalid arguments to '" + type.displayName() +
2022 "' constructor (expected " + to_string(expected) +
2023 " scalars, but found " + to_string(actual) + ")");
2024 return nullptr;
2025 }
2026 }
2027 return std::unique_ptr<Expression>(new Constructor(offset, type, std::move(args)));
2028}
2029
2030std::unique_ptr<Expression> IRGenerator::convertConstructor(
2031 int offset,
2032 const Type& type,
2033 std::vector<std::unique_ptr<Expression>> args) {
2034 // FIXME: add support for structs
2035 Type::Kind kind = type.kind();
2036 if (args.size() == 1 && args[0]->fType == type) {
2037 // argument is already the right type, just return it
2038 return std::move(args[0]);
2039 }
2040 if (type.isNumber()) {
2041 return this->convertNumberConstructor(offset, type, std::move(args));
2042 } else if (kind == Type::kArray_Kind) {
2043 const Type& base = type.componentType();
2044 for (size_t i = 0; i < args.size(); i++) {
2045 args[i] = this->coerce(std::move(args[i]), base);
2046 if (!args[i]) {
2047 return nullptr;
2048 }
2049 }
2050 return std::unique_ptr<Expression>(new Constructor(offset, type, std::move(args)));
2051 } else if (kind == Type::kVector_Kind || kind == Type::kMatrix_Kind) {
2052 return this->convertCompoundConstructor(offset, type, std::move(args));
2053 } else {
2054 fErrors.error(offset, "cannot construct '" + type.displayName() + "'");
2055 return nullptr;
2056 }
2057}
2058
2059std::unique_ptr<Expression> IRGenerator::convertPrefixExpression(const ASTNode& expression) {
2060 SkASSERT(expression.fKind == ASTNode::Kind::kPrefix);
2061 std::unique_ptr<Expression> base = this->convertExpression(*expression.begin());
2062 if (!base) {
2063 return nullptr;
2064 }
2065 switch (expression.getToken().fKind) {
2066 case Token::PLUS:
2067 if (!base->fType.isNumber() && base->fType.kind() != Type::kVector_Kind &&
2068 base->fType != *fContext.fFloatLiteral_Type) {
2069 fErrors.error(expression.fOffset,
2070 "'+' cannot operate on '" + base->fType.displayName() + "'");
2071 return nullptr;
2072 }
2073 return base;
2074 case Token::MINUS:
2075 if (base->fKind == Expression::kIntLiteral_Kind) {
2076 return std::unique_ptr<Expression>(new IntLiteral(fContext, base->fOffset,
2077 -((IntLiteral&) *base).fValue));
2078 }
2079 if (base->fKind == Expression::kFloatLiteral_Kind) {
2080 double value = -((FloatLiteral&) *base).fValue;
2081 return std::unique_ptr<Expression>(new FloatLiteral(fContext, base->fOffset,
2082 value));
2083 }
2084 if (!base->fType.isNumber() && base->fType.kind() != Type::kVector_Kind) {
2085 fErrors.error(expression.fOffset,
2086 "'-' cannot operate on '" + base->fType.displayName() + "'");
2087 return nullptr;
2088 }
2089 return std::unique_ptr<Expression>(new PrefixExpression(Token::MINUS, std::move(base)));
2090 case Token::PLUSPLUS:
2091 if (!base->fType.isNumber()) {
2092 fErrors.error(expression.fOffset,
2093 String("'") + Compiler::OperatorName(expression.getToken().fKind) +
2094 "' cannot operate on '" + base->fType.displayName() + "'");
2095 return nullptr;
2096 }
2097 this->setRefKind(*base, VariableReference::kReadWrite_RefKind);
2098 break;
2099 case Token::MINUSMINUS:
2100 if (!base->fType.isNumber()) {
2101 fErrors.error(expression.fOffset,
2102 String("'") + Compiler::OperatorName(expression.getToken().fKind) +
2103 "' cannot operate on '" + base->fType.displayName() + "'");
2104 return nullptr;
2105 }
2106 this->setRefKind(*base, VariableReference::kReadWrite_RefKind);
2107 break;
2108 case Token::LOGICALNOT:
2109 if (base->fType != *fContext.fBool_Type) {
2110 fErrors.error(expression.fOffset,
2111 String("'") + Compiler::OperatorName(expression.getToken().fKind) +
2112 "' cannot operate on '" + base->fType.displayName() + "'");
2113 return nullptr;
2114 }
2115 if (base->fKind == Expression::kBoolLiteral_Kind) {
2116 return std::unique_ptr<Expression>(new BoolLiteral(fContext, base->fOffset,
2117 !((BoolLiteral&) *base).fValue));
2118 }
2119 break;
2120 case Token::BITWISENOT:
2121 if (base->fType != *fContext.fInt_Type && base->fType != *fContext.fUInt_Type) {
2122 fErrors.error(expression.fOffset,
2123 String("'") + Compiler::OperatorName(expression.getToken().fKind) +
2124 "' cannot operate on '" + base->fType.displayName() + "'");
2125 return nullptr;
2126 }
2127 break;
2128 default:
2129 ABORT("unsupported prefix operator\n");
2130 }
2131 return std::unique_ptr<Expression>(new PrefixExpression(expression.getToken().fKind,
2132 std::move(base)));
2133}
2134
2135std::unique_ptr<Expression> IRGenerator::convertIndex(std::unique_ptr<Expression> base,
2136 const ASTNode& index) {
2137 if (base->fKind == Expression::kTypeReference_Kind) {
2138 if (index.fKind == ASTNode::Kind::kInt) {
2139 const Type& oldType = ((TypeReference&) *base).fValue;
2140 SKSL_INT size = index.getInt();
2141 Type* newType = (Type*) fSymbolTable->takeOwnership(std::unique_ptr<Symbol>(
2142 new Type(oldType.name() + "[" + to_string(size) + "]",
2143 Type::kArray_Kind, oldType, size)));
2144 return std::unique_ptr<Expression>(new TypeReference(fContext, base->fOffset,
2145 *newType));
2146
2147 } else {
2148 fErrors.error(base->fOffset, "array size must be a constant");
2149 return nullptr;
2150 }
2151 }
2152 if (base->fType.kind() != Type::kArray_Kind && base->fType.kind() != Type::kMatrix_Kind &&
2153 base->fType.kind() != Type::kVector_Kind) {
2154 fErrors.error(base->fOffset, "expected array, but found '" + base->fType.displayName() +
2155 "'");
2156 return nullptr;
2157 }
2158 std::unique_ptr<Expression> converted = this->convertExpression(index);
2159 if (!converted) {
2160 return nullptr;
2161 }
2162 if (converted->fType != *fContext.fUInt_Type) {
2163 converted = this->coerce(std::move(converted), *fContext.fInt_Type);
2164 if (!converted) {
2165 return nullptr;
2166 }
2167 }
2168 return std::unique_ptr<Expression>(new IndexExpression(fContext, std::move(base),
2169 std::move(converted)));
2170}
2171
2172std::unique_ptr<Expression> IRGenerator::convertField(std::unique_ptr<Expression> base,
2173 StringFragment field) {
2174 if (base->fKind == Expression::kExternalValue_Kind) {
2175 ExternalValue& ev = *((ExternalValueReference&) *base).fValue;
2176 ExternalValue* result = ev.getChild(String(field).c_str());
2177 if (!result) {
2178 fErrors.error(base->fOffset, "external value does not have a child named '" + field +
2179 "'");
2180 return nullptr;
2181 }
2182 return std::unique_ptr<Expression>(new ExternalValueReference(base->fOffset, result));
2183 }
2184 auto fields = base->fType.fields();
2185 for (size_t i = 0; i < fields.size(); i++) {
2186 if (fields[i].fName == field) {
2187 return std::unique_ptr<Expression>(new FieldAccess(std::move(base), (int) i));
2188 }
2189 }
2190 fErrors.error(base->fOffset, "type '" + base->fType.displayName() + "' does not have a "
2191 "field named '" + field + "");
2192 return nullptr;
2193}
2194
2195std::unique_ptr<Expression> IRGenerator::convertSwizzle(std::unique_ptr<Expression> base,
2196 StringFragment fields) {
2197 if (base->fType.kind() != Type::kVector_Kind) {
2198 fErrors.error(base->fOffset, "cannot swizzle type '" + base->fType.displayName() + "'");
2199 return nullptr;
2200 }
2201 std::vector<int> swizzleComponents;
2202 for (size_t i = 0; i < fields.fLength; i++) {
2203 switch (fields[i]) {
2204 case '0':
2205 swizzleComponents.push_back(SKSL_SWIZZLE_0);
2206 break;
2207 case '1':
2208 swizzleComponents.push_back(SKSL_SWIZZLE_1);
2209 break;
2210 case 'x':
2211 case 'r':
2212 case 's':
2213 case 'L':
2214 swizzleComponents.push_back(0);
2215 break;
2216 case 'y':
2217 case 'g':
2218 case 't':
2219 case 'T':
2220 if (base->fType.columns() >= 2) {
2221 swizzleComponents.push_back(1);
2222 break;
2223 }
2224 // fall through
2225 case 'z':
2226 case 'b':
2227 case 'p':
2228 case 'R':
2229 if (base->fType.columns() >= 3) {
2230 swizzleComponents.push_back(2);
2231 break;
2232 }
2233 // fall through
2234 case 'w':
2235 case 'a':
2236 case 'q':
2237 case 'B':
2238 if (base->fType.columns() >= 4) {
2239 swizzleComponents.push_back(3);
2240 break;
2241 }
2242 // fall through
2243 default:
2244 fErrors.error(base->fOffset, String::printf("invalid swizzle component '%c'",
2245 fields[i]));
2246 return nullptr;
2247 }
2248 }
2249 SkASSERT(swizzleComponents.size() > 0);
2250 if (swizzleComponents.size() > 4) {
2251 fErrors.error(base->fOffset, "too many components in swizzle mask '" + fields + "'");
2252 return nullptr;
2253 }
2254 return std::unique_ptr<Expression>(new Swizzle(fContext, std::move(base), swizzleComponents));
2255}
2256
2257std::unique_ptr<Expression> IRGenerator::getCap(int offset, String name) {
2258 auto found = fCapsMap.find(name);
2259 if (found == fCapsMap.end()) {
2260 fErrors.error(offset, "unknown capability flag '" + name + "'");
2261 return nullptr;
2262 }
2263 String fullName = "sk_Caps." + name;
2264 return std::unique_ptr<Expression>(new Setting(offset, fullName,
2265 found->second.literal(fContext, offset)));
2266}
2267
2268std::unique_ptr<Expression> IRGenerator::getArg(int offset, String name) const {
2269 auto found = fSettings->fArgs.find(name);
2270 if (found == fSettings->fArgs.end()) {
2271 return nullptr;
2272 }
2273 String fullName = "sk_Args." + name;
2274 return std::unique_ptr<Expression>(new Setting(offset,
2275 fullName,
2276 found->second.literal(fContext, offset)));
2277}
2278
2279std::unique_ptr<Expression> IRGenerator::convertTypeField(int offset, const Type& type,
2280 StringFragment field) {
2281 std::unique_ptr<Expression> result;
2282 for (const auto& e : *fProgramElements) {
2283 if (e->fKind == ProgramElement::kEnum_Kind && type.name() == ((Enum&) *e).fTypeName) {
2284 std::shared_ptr<SymbolTable> old = fSymbolTable;
2285 fSymbolTable = ((Enum&) *e).fSymbols;
2286 result = convertIdentifier(ASTNode(&fFile->fNodes, offset, ASTNode::Kind::kIdentifier,
2287 field));
2288 SkASSERT(result->fKind == Expression::kVariableReference_Kind);
2289 const Variable& v = ((VariableReference&) *result).fVariable;
2290 SkASSERT(v.fInitialValue);
2291 SkASSERT(v.fInitialValue->fKind == Expression::kIntLiteral_Kind);
2292 result.reset(new IntLiteral(offset, ((IntLiteral&) *v.fInitialValue).fValue, &type));
2293 fSymbolTable = old;
2294 break;
2295 }
2296 }
2297 if (!result) {
2298 auto found = fIntrinsics->find(type.fName);
2299 if (found != fIntrinsics->end()) {
2300 SkASSERT(!found->second.second);
2301 found->second.second = true;
2302 fProgramElements->push_back(found->second.first->clone());
2303 return this->convertTypeField(offset, type, field);
2304 }
2305 fErrors.error(offset, "type '" + type.fName + "' does not have a field named '" + field +
2306 "'");
2307 }
2308 return result;
2309}
2310
2311std::unique_ptr<Expression> IRGenerator::convertIndexExpression(const ASTNode& index) {
2312 SkASSERT(index.fKind == ASTNode::Kind::kIndex);
2313 auto iter = index.begin();
2314 std::unique_ptr<Expression> base = this->convertExpression(*(iter++));
2315 if (!base) {
2316 return nullptr;
2317 }
2318 if (iter != index.end()) {
2319 return this->convertIndex(std::move(base), *(iter++));
2320 } else if (base->fKind == Expression::kTypeReference_Kind) {
2321 const Type& oldType = ((TypeReference&) *base).fValue;
2322 Type* newType = (Type*) fSymbolTable->takeOwnership(std::unique_ptr<Symbol>(
2323 new Type(oldType.name() + "[]",
2324 Type::kArray_Kind,
2325 oldType,
2326 -1)));
2327 return std::unique_ptr<Expression>(new TypeReference(fContext, base->fOffset,
2328 *newType));
2329 }
2330 fErrors.error(index.fOffset, "'[]' must follow a type name");
2331 return nullptr;
2332}
2333
2334std::unique_ptr<Expression> IRGenerator::convertCallExpression(const ASTNode& callNode) {
2335 SkASSERT(callNode.fKind == ASTNode::Kind::kCall);
2336 auto iter = callNode.begin();
2337 std::unique_ptr<Expression> base = this->convertExpression(*(iter++));
2338 if (!base) {
2339 return nullptr;
2340 }
2341 std::vector<std::unique_ptr<Expression>> arguments;
2342 for (; iter != callNode.end(); ++iter) {
2343 std::unique_ptr<Expression> converted = this->convertExpression(*iter);
2344 if (!converted) {
2345 return nullptr;
2346 }
2347 arguments.push_back(std::move(converted));
2348 }
2349 return this->call(callNode.fOffset, std::move(base), std::move(arguments));
2350}
2351
2352std::unique_ptr<Expression> IRGenerator::convertFieldExpression(const ASTNode& fieldNode) {
2353 std::unique_ptr<Expression> base = this->convertExpression(*fieldNode.begin());
2354 if (!base) {
2355 return nullptr;
2356 }
2357 StringFragment field = fieldNode.getString();
2358 if (base->fType == *fContext.fSkCaps_Type) {
2359 return this->getCap(fieldNode.fOffset, field);
2360 }
2361 if (base->fType == *fContext.fSkArgs_Type) {
2362 return this->getArg(fieldNode.fOffset, field);
2363 }
2364 if (base->fKind == Expression::kTypeReference_Kind) {
2365 return this->convertTypeField(base->fOffset, ((TypeReference&) *base).fValue,
2366 field);
2367 }
2368 if (base->fKind == Expression::kExternalValue_Kind) {
2369 return this->convertField(std::move(base), field);
2370 }
2371 switch (base->fType.kind()) {
2372 case Type::kVector_Kind:
2373 return this->convertSwizzle(std::move(base), field);
2374 case Type::kOther_Kind:
2375 case Type::kStruct_Kind:
2376 return this->convertField(std::move(base), field);
2377 default:
2378 fErrors.error(base->fOffset, "cannot swizzle value of type '" +
2379 base->fType.displayName() + "'");
2380 return nullptr;
2381 }
2382}
2383
2384std::unique_ptr<Expression> IRGenerator::convertPostfixExpression(const ASTNode& expression) {
2385 std::unique_ptr<Expression> base = this->convertExpression(*expression.begin());
2386 if (!base) {
2387 return nullptr;
2388 }
2389 if (!base->fType.isNumber()) {
2390 fErrors.error(expression.fOffset,
2391 "'" + String(Compiler::OperatorName(expression.getToken().fKind)) +
2392 "' cannot operate on '" + base->fType.displayName() + "'");
2393 return nullptr;
2394 }
2395 this->setRefKind(*base, VariableReference::kReadWrite_RefKind);
2396 return std::unique_ptr<Expression>(new PostfixExpression(std::move(base),
2397 expression.getToken().fKind));
2398}
2399
2400void IRGenerator::checkValid(const Expression& expr) {
2401 switch (expr.fKind) {
2402 case Expression::kFunctionReference_Kind:
2403 fErrors.error(expr.fOffset, "expected '(' to begin function call");
2404 break;
2405 case Expression::kTypeReference_Kind:
2406 fErrors.error(expr.fOffset, "expected '(' to begin constructor invocation");
2407 break;
2408 default:
2409 if (expr.fType == *fContext.fInvalid_Type) {
2410 fErrors.error(expr.fOffset, "invalid expression");
2411 }
2412 }
2413}
2414
2415bool IRGenerator::checkSwizzleWrite(const Swizzle& swizzle) {
2416 int bits = 0;
2417 for (int idx : swizzle.fComponents) {
2418 if (idx < 0) {
2419 fErrors.error(swizzle.fOffset, "cannot write to a swizzle mask containing a constant");
2420 return false;
2421 }
2422 SkASSERT(idx <= 3);
2423 int bit = 1 << idx;
2424 if (bits & bit) {
2425 fErrors.error(swizzle.fOffset,
2426 "cannot write to the same swizzle field more than once");
2427 return false;
2428 }
2429 bits |= bit;
2430 }
2431 return true;
2432}
2433
2434void IRGenerator::setRefKind(const Expression& expr, VariableReference::RefKind kind) {
2435 switch (expr.fKind) {
2436 case Expression::kVariableReference_Kind: {
2437 const Variable& var = ((VariableReference&) expr).fVariable;
2438 if (var.fModifiers.fFlags &
2439 (Modifiers::kConst_Flag | Modifiers::kUniform_Flag | Modifiers::kVarying_Flag)) {
2440 fErrors.error(expr.fOffset, "cannot modify immutable variable '" + var.fName + "'");
2441 }
2442 ((VariableReference&) expr).setRefKind(kind);
2443 break;
2444 }
2445 case Expression::kFieldAccess_Kind:
2446 this->setRefKind(*((FieldAccess&) expr).fBase, kind);
2447 break;
2448 case Expression::kSwizzle_Kind: {
2449 const Swizzle& swizzle = (Swizzle&) expr;
2450 this->checkSwizzleWrite(swizzle);
2451 this->setRefKind(*swizzle.fBase, kind);
2452 break;
2453 }
2454 case Expression::kIndex_Kind:
2455 this->setRefKind(*((IndexExpression&) expr).fBase, kind);
2456 break;
2457 case Expression::kTernary_Kind: {
2458 TernaryExpression& t = (TernaryExpression&) expr;
2459 this->setRefKind(*t.fIfTrue, kind);
2460 this->setRefKind(*t.fIfFalse, kind);
2461 break;
2462 }
2463 case Expression::kExternalValue_Kind: {
2464 const ExternalValue& v = *((ExternalValueReference&) expr).fValue;
2465 if (!v.canWrite()) {
2466 fErrors.error(expr.fOffset,
2467 "cannot modify immutable external value '" + v.fName + "'");
2468 }
2469 break;
2470 }
2471 default:
2472 fErrors.error(expr.fOffset, "cannot assign to this expression");
2473 break;
2474 }
2475}
2476
2477void IRGenerator::convertProgram(Program::Kind kind,
2478 const char* text,
2479 size_t length,
2480 SymbolTable& types,
2481 std::vector<std::unique_ptr<ProgramElement>>* out) {
2482 fKind = kind;
2483 fProgramElements = out;
2484 Parser parser(text, length, types, fErrors);
2485 fFile = parser.file();
2486 if (fErrors.errorCount()) {
2487 return;
2488 }
2489 SkASSERT(fFile);
2490 for (const auto& decl : fFile->root()) {
2491 switch (decl.fKind) {
2492 case ASTNode::Kind::kVarDeclarations: {
2493 std::unique_ptr<VarDeclarations> s = this->convertVarDeclarations(
2494 decl,
2495 Variable::kGlobal_Storage);
2496 if (s) {
2497 fProgramElements->push_back(std::move(s));
2498 }
2499 break;
2500 }
2501 case ASTNode::Kind::kEnum: {
2502 this->convertEnum(decl);
2503 break;
2504 }
2505 case ASTNode::Kind::kFunction: {
2506 this->convertFunction(decl);
2507 break;
2508 }
2509 case ASTNode::Kind::kModifiers: {
2510 std::unique_ptr<ModifiersDeclaration> f = this->convertModifiersDeclaration(decl);
2511 if (f) {
2512 fProgramElements->push_back(std::move(f));
2513 }
2514 break;
2515 }
2516 case ASTNode::Kind::kInterfaceBlock: {
2517 std::unique_ptr<InterfaceBlock> i = this->convertInterfaceBlock(decl);
2518 if (i) {
2519 fProgramElements->push_back(std::move(i));
2520 }
2521 break;
2522 }
2523 case ASTNode::Kind::kExtension: {
2524 std::unique_ptr<Extension> e = this->convertExtension(decl.fOffset,
2525 decl.getString());
2526 if (e) {
2527 fProgramElements->push_back(std::move(e));
2528 }
2529 break;
2530 }
2531 case ASTNode::Kind::kSection: {
2532 std::unique_ptr<Section> s = this->convertSection(decl);
2533 if (s) {
2534 fProgramElements->push_back(std::move(s));
2535 }
2536 break;
2537 }
2538 default:
2539#ifdef SK_DEBUG
2540 ABORT("unsupported declaration: %s\n", decl.description().c_str());
2541#endif
2542 break;
2543 }
2544 }
2545}
2546
2547
2548}
2549