• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 Google LLC
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 "include/sksl/DSLExpression.h"
9 
10 #include "include/core/SkTypes.h"
11 #include "include/private/SkSLDefines.h"
12 #include "include/sksl/DSLCore.h"
13 #include "include/sksl/DSLType.h"
14 #include "include/sksl/DSLVar.h"
15 #include "include/sksl/SkSLOperator.h"
16 #include "src/sksl/SkSLThreadContext.h"
17 #include "src/sksl/dsl/priv/DSLWriter.h"
18 #include "src/sksl/ir/SkSLBinaryExpression.h"
19 #include "src/sksl/ir/SkSLExpression.h"
20 #include "src/sksl/ir/SkSLFieldAccess.h"
21 #include "src/sksl/ir/SkSLFunctionCall.h"
22 #include "src/sksl/ir/SkSLIndexExpression.h"
23 #include "src/sksl/ir/SkSLLiteral.h"
24 #include "src/sksl/ir/SkSLPoison.h"
25 #include "src/sksl/ir/SkSLPostfixExpression.h"
26 #include "src/sksl/ir/SkSLPrefixExpression.h"
27 #include "src/sksl/ir/SkSLVariableReference.h"
28 
29 #include <utility>
30 
31 namespace SkSL {
32 
33 namespace dsl {
34 
DSLExpression()35 DSLExpression::DSLExpression() {}
36 
DSLExpression(DSLExpression && other)37 DSLExpression::DSLExpression(DSLExpression&& other)
38     : fExpression(std::move(other.fExpression)) {}
39 
DSLExpression(std::unique_ptr<SkSL::Expression> expression,Position pos)40 DSLExpression::DSLExpression(std::unique_ptr<SkSL::Expression> expression, Position pos)
41     : fExpression(expression ? std::move(expression)
42                              : SkSL::Poison::Make(pos, ThreadContext::Context())) {
43     // If a position was passed in, it must match the expression's position.
44     SkASSERTF(!pos.valid() || this->position() == pos,
45               "expected expression position (%d-%d), but received (%d-%d)",
46               pos.startOffset(), pos.endOffset(),
47               this->position().startOffset(), this->position().endOffset());
48 }
49 
DSLExpression(float value,Position pos)50 DSLExpression::DSLExpression(float value, Position pos)
51     : fExpression(SkSL::Literal::MakeFloat(ThreadContext::Context(),
52                                            pos,
53                                            value)) {}
54 
DSLExpression(int value,Position pos)55 DSLExpression::DSLExpression(int value, Position pos)
56     : fExpression(SkSL::Literal::MakeInt(ThreadContext::Context(),
57                                          pos,
58                                          value)) {}
59 
DSLExpression(int64_t value,Position pos)60 DSLExpression::DSLExpression(int64_t value, Position pos)
61     : fExpression(SkSL::Literal::MakeInt(ThreadContext::Context(),
62                                          pos,
63                                          value)) {}
64 
DSLExpression(unsigned int value,Position pos)65 DSLExpression::DSLExpression(unsigned int value, Position pos)
66     : fExpression(SkSL::Literal::MakeInt(ThreadContext::Context(),
67                                          pos,
68                                          value)) {}
69 
DSLExpression(bool value,Position pos)70 DSLExpression::DSLExpression(bool value, Position pos)
71     : fExpression(SkSL::Literal::MakeBool(ThreadContext::Context(),
72                                           pos,
73                                           value)) {}
74 
DSLExpression(DSLVarBase & var,Position pos)75 DSLExpression::DSLExpression(DSLVarBase& var, Position pos)
76     : fExpression(std::make_unique<SkSL::VariableReference>(
77                   pos, DSLWriter::Var(var), SkSL::VariableReference::RefKind::kRead)) {}
78 
DSLExpression(DSLVarBase && var,Position pos)79 DSLExpression::DSLExpression(DSLVarBase&& var, Position pos)
80     : DSLExpression(var) {}
81 
~DSLExpression()82 DSLExpression::~DSLExpression() {}
83 
Poison(Position pos)84 DSLExpression DSLExpression::Poison(Position pos) {
85     return DSLExpression(SkSL::Poison::Make(pos, ThreadContext::Context()));
86 }
87 
isValid() const88 bool DSLExpression::isValid() const {
89     return this->hasValue() && !fExpression->is<SkSL::Poison>();
90 }
91 
swap(DSLExpression & other)92 void DSLExpression::swap(DSLExpression& other) {
93     std::swap(fExpression, other.fExpression);
94 }
95 
release()96 std::unique_ptr<SkSL::Expression> DSLExpression::release() {
97     SkASSERT(this->hasValue());
98     return std::move(fExpression);
99 }
100 
releaseIfPossible()101 std::unique_ptr<SkSL::Expression> DSLExpression::releaseIfPossible() {
102     return std::move(fExpression);
103 }
104 
type() const105 DSLType DSLExpression::type() const {
106     if (!this->hasValue()) {
107         return kVoid_Type;
108     }
109     return &fExpression->type();
110 }
111 
description() const112 std::string DSLExpression::description() const {
113     SkASSERT(this->hasValue());
114     return fExpression->description();
115 }
116 
position() const117 Position DSLExpression::position() const {
118     SkASSERT(this->hasValue());
119     return fExpression->fPosition;
120 }
121 
setPosition(Position pos)122 void DSLExpression::setPosition(Position pos) {
123     SkASSERT(this->hasValue());
124     fExpression->fPosition = pos;
125 }
126 
x(Position pos)127 DSLExpression DSLExpression::x(Position pos) {
128     return Swizzle(std::move(*this), X, pos);
129 }
130 
y(Position pos)131 DSLExpression DSLExpression::y(Position pos) {
132     return Swizzle(std::move(*this), Y, pos);
133 }
134 
z(Position pos)135 DSLExpression DSLExpression::z(Position pos) {
136     return Swizzle(std::move(*this), Z, pos);
137 }
138 
w(Position pos)139 DSLExpression DSLExpression::w(Position pos) {
140     return Swizzle(std::move(*this), W, pos);
141 }
142 
r(Position pos)143 DSLExpression DSLExpression::r(Position pos) {
144     return Swizzle(std::move(*this), R, pos);
145 }
146 
g(Position pos)147 DSLExpression DSLExpression::g(Position pos) {
148     return Swizzle(std::move(*this), G, pos);
149 }
150 
b(Position pos)151 DSLExpression DSLExpression::b(Position pos) {
152     return Swizzle(std::move(*this), B, pos);
153 }
154 
a(Position pos)155 DSLExpression DSLExpression::a(Position pos) {
156     return Swizzle(std::move(*this), A, pos);
157 }
158 
field(std::string_view name,Position pos)159 DSLExpression DSLExpression::field(std::string_view name, Position pos) {
160     return DSLExpression(FieldAccess::Convert(ThreadContext::Context(), pos,
161             *ThreadContext::SymbolTable(), this->release(), name), pos);
162 }
163 
assign(DSLExpression right)164 DSLExpression DSLExpression::assign(DSLExpression right) {
165     Position pos = this->position().rangeThrough(right.position());
166     return DSLExpression(BinaryExpression::Convert(ThreadContext::Context(), pos, this->release(),
167                                                    SkSL::Operator::Kind::EQ, right.release()));
168 }
169 
operator [](DSLExpression right)170 DSLExpression DSLExpression::operator[](DSLExpression right) {
171     Position pos = this->position().rangeThrough(right.position());
172     return DSLExpression(IndexExpression::Convert(ThreadContext::Context(),
173                                                   *ThreadContext::SymbolTable(), pos,
174                                                   this->release(), right.release()));
175 }
176 
index(DSLExpression index,Position pos)177 DSLExpression DSLExpression::index(DSLExpression index, Position pos) {
178     std::unique_ptr<SkSL::Expression> result = IndexExpression::Convert(ThreadContext::Context(),
179             *ThreadContext::SymbolTable(), pos, this->release(), index.release());
180     return DSLExpression(std::move(result), pos);
181 }
182 
operator ()(SkTArray<DSLExpression> args,Position pos)183 DSLExpression DSLExpression::operator()(SkTArray<DSLExpression> args, Position pos) {
184     ExpressionArray converted;
185     converted.reserve_back(args.size());
186     for (DSLExpression& arg : args) {
187         converted.push_back(arg.release());
188     }
189     return (*this)(std::move(converted), pos);
190 }
191 
operator ()(ExpressionArray args,Position pos)192 DSLExpression DSLExpression::operator()(ExpressionArray args, Position pos) {
193     return DSLExpression(SkSL::FunctionCall::Convert(ThreadContext::Context(), pos, this->release(),
194                                                      std::move(args)), pos);
195 }
196 
prefix(Operator::Kind op,Position pos)197 DSLExpression DSLExpression::prefix(Operator::Kind op, Position pos) {
198     std::unique_ptr<SkSL::Expression> result = PrefixExpression::Convert(ThreadContext::Context(),
199                                                                          pos, op, this->release());
200     return DSLExpression(std::move(result), pos);
201 }
202 
postfix(Operator::Kind op,Position pos)203 DSLExpression DSLExpression::postfix(Operator::Kind op, Position pos) {
204     std::unique_ptr<SkSL::Expression> result = PostfixExpression::Convert(ThreadContext::Context(),
205                                                                           pos, this->release(), op);
206     return DSLExpression(std::move(result), pos);
207 }
208 
binary(Operator::Kind op,DSLExpression right,Position pos)209 DSLExpression DSLExpression::binary(Operator::Kind op, DSLExpression right, Position pos) {
210     std::unique_ptr<SkSL::Expression> result = BinaryExpression::Convert(ThreadContext::Context(),
211             pos, this->release(), op, right.release());
212     return DSLExpression(std::move(result), pos);
213 }
214 
215 #define OP(op, token)                                                        \
216 DSLExpression operator op(DSLExpression left, DSLExpression right) {         \
217     return DSLExpression(BinaryExpression::Convert(ThreadContext::Context(), \
218                                                    Position(),               \
219                                                    left.release(),           \
220                                                    Operator::Kind::token,    \
221                                                    right.release()));        \
222 }
223 
224 #define PREFIXOP(op, token)                                                  \
225 DSLExpression operator op(DSLExpression expr) {                              \
226     return DSLExpression(PrefixExpression::Convert(ThreadContext::Context(), \
227                                                    Position(),               \
228                                                    Operator::Kind::token,    \
229                                                    expr.release()));         \
230 }
231 
232 #define POSTFIXOP(op, token)                                                  \
233 DSLExpression operator op(DSLExpression expr, int) {                          \
234     return DSLExpression(PostfixExpression::Convert(ThreadContext::Context(), \
235                                                     Position(),               \
236                                                     expr.release(),           \
237                                                     Operator::Kind::token));  \
238 }
239 
240 OP(+, PLUS)
241 OP(+=, PLUSEQ)
242 OP(-, MINUS)
243 OP(-=, MINUSEQ)
244 OP(*, STAR)
245 OP(*=, STAREQ)
246 OP(/, SLASH)
247 OP(/=, SLASHEQ)
248 OP(%, PERCENT)
249 OP(%=, PERCENTEQ)
250 OP(<<, SHL)
251 OP(<<=, SHLEQ)
252 OP(>>, SHR)
253 OP(>>=, SHREQ)
254 OP(&&, LOGICALAND)
255 OP(||, LOGICALOR)
256 OP(&, BITWISEAND)
257 OP(&=, BITWISEANDEQ)
258 OP(|, BITWISEOR)
259 OP(|=, BITWISEOREQ)
260 OP(^, BITWISEXOR)
261 OP(^=, BITWISEXOREQ)
LogicalXor(DSLExpression left,DSLExpression right)262 DSLExpression LogicalXor(DSLExpression left, DSLExpression right) {
263     return DSLExpression(BinaryExpression::Convert(ThreadContext::Context(),
264                                                    Position(),
265                                                    left.release(),
266                                                    SkSL::Operator::Kind::LOGICALXOR,
267                                                    right.release()));
268 }
269 OP(==, EQEQ)
270 OP(!=, NEQ)
271 OP(>, GT)
272 OP(<, LT)
273 OP(>=, GTEQ)
274 OP(<=, LTEQ)
275 
276 PREFIXOP(+, PLUS)
277 PREFIXOP(-, MINUS)
278 PREFIXOP(!, LOGICALNOT)
279 PREFIXOP(~, BITWISENOT)
280 PREFIXOP(++, PLUSPLUS)
281 POSTFIXOP(++, PLUSPLUS)
282 PREFIXOP(--, MINUSMINUS)
283 POSTFIXOP(--, MINUSMINUS)
284 
operator ,(DSLExpression left,DSLExpression right)285 DSLExpression operator,(DSLExpression left, DSLExpression right) {
286     return DSLExpression(BinaryExpression::Convert(ThreadContext::Context(),
287                                                    Position(),
288                                                    left.release(),
289                                                    SkSL::Operator::Kind::COMMA,
290                                                    right.release()));
291 }
292 
293 } // namespace dsl
294 
295 } // namespace SkSL
296