diff options
Diffstat (limited to 'src/sksl/SkSLIRGenerator.cpp')
-rw-r--r-- | src/sksl/SkSLIRGenerator.cpp | 78 |
1 files changed, 26 insertions, 52 deletions
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp index 9f06c97d11..55d9d2c8d6 100644 --- a/src/sksl/SkSLIRGenerator.cpp +++ b/src/sksl/SkSLIRGenerator.cpp @@ -551,11 +551,11 @@ std::unique_ptr<InterfaceBlock> IRGenerator::convertInterfaceBlock(const ASTInte } } Type* type = new Type(intf.fPosition, intf.fInterfaceName, fields); - fSymbolTable->takeOwnership(type); + old->takeOwnership(type); SkString name = intf.fValueName.size() > 0 ? intf.fValueName : intf.fInterfaceName; Variable* var = new Variable(intf.fPosition, intf.fModifiers, name, *type, Variable::kGlobal_Storage); - fSymbolTable->takeOwnership(var); + old->takeOwnership(var); if (intf.fValueName.size()) { old->addWithoutOwnership(intf.fValueName, var); } else { @@ -624,19 +624,22 @@ std::unique_ptr<Expression> IRGenerator::convertIdentifier(const ASTIdentifier& f->fFunctions)); } case Symbol::kVariable_Kind: { - const Variable* var = (const Variable*) result; - this->markReadFrom(*var); + Variable* var = (Variable*) result; if (var->fModifiers.fLayout.fBuiltin == SK_FRAGCOORD_BUILTIN && fSettings->fFlipY && (!fSettings->fCaps || !fSettings->fCaps->fragCoordConventionsExtensionString())) { fInputs.fRTHeight = true; } - return std::unique_ptr<VariableReference>(new VariableReference(identifier.fPosition, - *var)); + // default to kRead_RefKind; this will be corrected later if the variable is written to + return std::unique_ptr<VariableReference>(new VariableReference( + identifier.fPosition, + *var, + VariableReference::kRead_RefKind)); } case Symbol::kField_Kind: { const Field* field = (const Field*) result; - VariableReference* base = new VariableReference(identifier.fPosition, field->fOwner); + VariableReference* base = new VariableReference(identifier.fPosition, field->fOwner, + VariableReference::kRead_RefKind); return std::unique_ptr<Expression>(new FieldAccess( std::unique_ptr<Expression>(base), field->fFieldIndex, @@ -690,28 +693,6 @@ static bool is_matrix_multiply(const Type& left, const Type& right) { return left.kind() == Type::kVector_Kind && right.kind() == Type::kMatrix_Kind; } -static bool is_assignment(Token::Kind op) { - switch (op) { - case Token::EQ: // fall through - case Token::PLUSEQ: // fall through - case Token::MINUSEQ: // fall through - case Token::STAREQ: // fall through - case Token::SLASHEQ: // fall through - case Token::PERCENTEQ: // fall through - case Token::SHLEQ: // fall through - case Token::SHREQ: // fall through - case Token::BITWISEOREQ: // fall through - case Token::BITWISEXOREQ: // fall through - case Token::BITWISEANDEQ: // fall through - case Token::LOGICALOREQ: // fall through - case Token::LOGICALXOREQ: // fall through - case Token::LOGICALANDEQ: - return true; - default: - return false; - } -} - /** * Determines the operand and result types of a binary expression. Returns true if the expression is * legal, false otherwise. If false, the values of the out parameters are undefined. @@ -842,14 +823,9 @@ static bool determine_binary_type(const Context& context, return false; } -/** - * If both operands are compile-time constants and can be folded, returns an expression representing - * the folded value. Otherwise, returns null. Note that unlike most other functions here, null does - * not represent a compilation error. - */ std::unique_ptr<Expression> IRGenerator::constantFold(const Expression& left, Token::Kind op, - const Expression& right) { + const Expression& right) const { // Note that we expressly do not worry about precision and overflow here -- we use the maximum // precision to calculate the results and hope the result makes sense. The plan is to move the // Skia caps into SkSL, so we have access to all of them including the precisions of the various @@ -943,15 +919,16 @@ std::unique_ptr<Expression> IRGenerator::convertBinaryExpression( const Type* rightType; const Type* resultType; if (!determine_binary_type(fContext, expression.fOperator, left->fType, right->fType, &leftType, - &rightType, &resultType, !is_assignment(expression.fOperator))) { + &rightType, &resultType, + !Token::IsAssignment(expression.fOperator))) { fErrors.error(expression.fPosition, "type mismatch: '" + Token::OperatorName(expression.fOperator) + "' cannot operate on '" + left->fType.fName + "', '" + right->fType.fName + "'"); return nullptr; } - if (is_assignment(expression.fOperator)) { - this->markWrittenTo(*left); + if (Token::IsAssignment(expression.fOperator)) { + this->markWrittenTo(*left, expression.fOperator != Token::EQ); } left = this->coerce(std::move(left), *leftType); right = this->coerce(std::move(right), *rightType); @@ -1051,7 +1028,7 @@ std::unique_ptr<Expression> IRGenerator::call(Position position, return nullptr; } if (arguments[i] && (function.fParameters[i]->fModifiers.fFlags & Modifiers::kOut_Flag)) { - this->markWrittenTo(*arguments[i]); + this->markWrittenTo(*arguments[i], true); } } return std::unique_ptr<FunctionCall>(new FunctionCall(position, *returnType, function, @@ -1261,7 +1238,7 @@ std::unique_ptr<Expression> IRGenerator::convertPrefixExpression( "' cannot operate on '" + base->fType.description() + "'"); return nullptr; } - this->markWrittenTo(*base); + this->markWrittenTo(*base, true); break; case Token::MINUSMINUS: if (!base->fType.isNumber()) { @@ -1270,7 +1247,7 @@ std::unique_ptr<Expression> IRGenerator::convertPrefixExpression( "' cannot operate on '" + base->fType.description() + "'"); return nullptr; } - this->markWrittenTo(*base); + this->markWrittenTo(*base, true); break; case Token::LOGICALNOT: if (base->fType != *fContext.fBool_Type) { @@ -1464,7 +1441,7 @@ std::unique_ptr<Expression> IRGenerator::convertSuffixExpression( "'++' cannot operate on '" + base->fType.description() + "'"); return nullptr; } - this->markWrittenTo(*base); + this->markWrittenTo(*base, true); return std::unique_ptr<Expression>(new PostfixExpression(std::move(base), Token::PLUSPLUS)); case ASTSuffix::kPostDecrement_Kind: @@ -1473,7 +1450,7 @@ std::unique_ptr<Expression> IRGenerator::convertSuffixExpression( "'--' cannot operate on '" + base->fType.description() + "'"); return nullptr; } - this->markWrittenTo(*base); + this->markWrittenTo(*base, true); return std::unique_ptr<Expression>(new PostfixExpression(std::move(base), Token::MINUSMINUS)); default: @@ -1496,10 +1473,6 @@ void IRGenerator::checkValid(const Expression& expr) { } } -void IRGenerator::markReadFrom(const Variable& var) { - var.fIsReadFrom = true; -} - static bool has_duplicates(const Swizzle& swizzle) { int bits = 0; for (int idx : swizzle.fComponents) { @@ -1513,7 +1486,7 @@ static bool has_duplicates(const Swizzle& swizzle) { return false; } -void IRGenerator::markWrittenTo(const Expression& expr) { +void IRGenerator::markWrittenTo(const Expression& expr, bool readWrite) { switch (expr.fKind) { case Expression::kVariableReference_Kind: { const Variable& var = ((VariableReference&) expr).fVariable; @@ -1521,21 +1494,22 @@ void IRGenerator::markWrittenTo(const Expression& expr) { fErrors.error(expr.fPosition, "cannot modify immutable variable '" + var.fName + "'"); } - var.fIsWrittenTo = true; + ((VariableReference&) expr).setRefKind(readWrite ? VariableReference::kReadWrite_RefKind + : VariableReference::kWrite_RefKind); break; } case Expression::kFieldAccess_Kind: - this->markWrittenTo(*((FieldAccess&) expr).fBase); + this->markWrittenTo(*((FieldAccess&) expr).fBase, readWrite); break; case Expression::kSwizzle_Kind: if (has_duplicates((Swizzle&) expr)) { fErrors.error(expr.fPosition, "cannot write to the same swizzle field more than once"); } - this->markWrittenTo(*((Swizzle&) expr).fBase); + this->markWrittenTo(*((Swizzle&) expr).fBase, readWrite); break; case Expression::kIndex_Kind: - this->markWrittenTo(*((IndexExpression&) expr).fBase); + this->markWrittenTo(*((IndexExpression&) expr).fBase, readWrite); break; default: fErrors.error(expr.fPosition, "cannot assign to '" + expr.description() + "'"); |