• 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/sksl/DSLCore.h"
11 #include "include/sksl/DSLVar.h"
12 #include "src/sksl/SkSLCompiler.h"
13 #include "src/sksl/SkSLThreadContext.h"
14 #include "src/sksl/dsl/priv/DSLWriter.h"
15 #include "src/sksl/ir/SkSLBinaryExpression.h"
16 #include "src/sksl/ir/SkSLFieldAccess.h"
17 #include "src/sksl/ir/SkSLFunctionCall.h"
18 #include "src/sksl/ir/SkSLIndexExpression.h"
19 #include "src/sksl/ir/SkSLLiteral.h"
20 #include "src/sksl/ir/SkSLPoison.h"
21 #include "src/sksl/ir/SkSLPostfixExpression.h"
22 #include "src/sksl/ir/SkSLPrefixExpression.h"
23 
24 #include "math.h"
25 
26 #if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
27 #include "src/gpu/glsl/GrGLSLFragmentShaderBuilder.h"
28 #endif
29 
30 namespace SkSL {
31 
32 namespace dsl {
33 
DSLExpression()34 DSLExpression::DSLExpression() {}
35 
DSLExpression(DSLExpression && other)36 DSLExpression::DSLExpression(DSLExpression&& other)
37     : fExpression(std::move(other.fExpression)) {}
38 
DSLExpression(std::unique_ptr<SkSL::Expression> expression)39 DSLExpression::DSLExpression(std::unique_ptr<SkSL::Expression> expression)
40     : fExpression(std::move(expression)) {
41     SkASSERT(this->hasValue());
42 }
43 
DSLExpression(float value,PositionInfo pos)44 DSLExpression::DSLExpression(float value, PositionInfo pos)
45     : fExpression(SkSL::Literal::MakeFloat(ThreadContext::Context(),
46                                            pos.line(),
47                                            value)) {
48     if (!isfinite(value)) {
49         if (isinf(value)) {
50             ThreadContext::ReportError("floating point value is infinite");
51         } else if (isnan(value)) {
52             ThreadContext::ReportError("floating point value is NaN");
53         }
54     }
55 }
56 
DSLExpression(int value,PositionInfo pos)57 DSLExpression::DSLExpression(int value, PositionInfo pos)
58     : fExpression(SkSL::Literal::MakeInt(ThreadContext::Context(),
59                                          pos.line(),
60                                          value)) {}
61 
DSLExpression(int64_t value,PositionInfo pos)62 DSLExpression::DSLExpression(int64_t value, PositionInfo pos)
63     : fExpression(SkSL::Literal::MakeInt(ThreadContext::Context(),
64                                          pos.line(),
65                                          value)) {}
66 
DSLExpression(unsigned int value,PositionInfo pos)67 DSLExpression::DSLExpression(unsigned int value, PositionInfo pos)
68     : fExpression(SkSL::Literal::MakeInt(ThreadContext::Context(),
69                                          pos.line(),
70                                          value)) {}
71 
DSLExpression(bool value,PositionInfo pos)72 DSLExpression::DSLExpression(bool value, PositionInfo pos)
73     : fExpression(SkSL::Literal::MakeBool(ThreadContext::Context(),
74                                           pos.line(),
75                                           value)) {}
76 
DSLExpression(DSLVarBase & var,PositionInfo pos)77 DSLExpression::DSLExpression(DSLVarBase& var, PositionInfo pos) {
78     fExpression = std::make_unique<SkSL::VariableReference>(pos.line(), DSLWriter::Var(var),
79             SkSL::VariableReference::RefKind::kRead);
80 }
81 
DSLExpression(DSLVarBase && var,PositionInfo pos)82 DSLExpression::DSLExpression(DSLVarBase&& var, PositionInfo pos)
83     : DSLExpression(var) {}
84 
DSLExpression(DSLPossibleExpression expr,PositionInfo pos)85 DSLExpression::DSLExpression(DSLPossibleExpression expr, PositionInfo pos) {
86     ThreadContext::ReportErrors(pos);
87     if (expr.valid()) {
88         fExpression = std::move(expr.fExpression);
89     } else {
90         fExpression = SkSL::Poison::Make(pos.line(), ThreadContext::Context());
91     }
92 }
93 
Poison(PositionInfo pos)94 DSLExpression DSLExpression::Poison(PositionInfo pos) {
95     return DSLExpression(SkSL::Poison::Make(pos.line(), ThreadContext::Context()));
96 }
97 
~DSLExpression()98 DSLExpression::~DSLExpression() {
99 #if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
100     if (fExpression && ThreadContext::InFragmentProcessor()) {
101         ThreadContext::CurrentEmitArgs()->fFragBuilder->codeAppend(
102                 DSLStatement(this->release()).release());
103         return;
104     }
105 #endif
106     SkASSERTF(!fExpression || !ThreadContext::Settings().fAssertDSLObjectsReleased,
107               "Expression destroyed without being incorporated into program (see "
108               "ProgramSettings::fAssertDSLObjectsReleased)");
109 }
110 
isValid() const111 bool DSLExpression::isValid() const {
112     return this->hasValue() && !fExpression->is<SkSL::Poison>();
113 }
114 
swap(DSLExpression & other)115 void DSLExpression::swap(DSLExpression& other) {
116     std::swap(fExpression, other.fExpression);
117 }
118 
release()119 std::unique_ptr<SkSL::Expression> DSLExpression::release() {
120     SkASSERT(this->hasValue());
121     return std::move(fExpression);
122 }
123 
releaseIfPossible()124 std::unique_ptr<SkSL::Expression> DSLExpression::releaseIfPossible() {
125     return std::move(fExpression);
126 }
127 
type()128 DSLType DSLExpression::type() {
129     if (!this->hasValue()) {
130         return kVoid_Type;
131     }
132     return &fExpression->type();
133 }
134 
x(PositionInfo pos)135 DSLExpression DSLExpression::x(PositionInfo pos) {
136     return Swizzle(std::move(*this), X, pos);
137 }
138 
y(PositionInfo pos)139 DSLExpression DSLExpression::y(PositionInfo pos) {
140     return Swizzle(std::move(*this), Y, pos);
141 }
142 
z(PositionInfo pos)143 DSLExpression DSLExpression::z(PositionInfo pos) {
144     return Swizzle(std::move(*this), Z, pos);
145 }
146 
w(PositionInfo pos)147 DSLExpression DSLExpression::w(PositionInfo pos) {
148     return Swizzle(std::move(*this), W, pos);
149 }
150 
r(PositionInfo pos)151 DSLExpression DSLExpression::r(PositionInfo pos) {
152     return Swizzle(std::move(*this), R, pos);
153 }
154 
g(PositionInfo pos)155 DSLExpression DSLExpression::g(PositionInfo pos) {
156     return Swizzle(std::move(*this), G, pos);
157 }
158 
b(PositionInfo pos)159 DSLExpression DSLExpression::b(PositionInfo pos) {
160     return Swizzle(std::move(*this), B, pos);
161 }
162 
a(PositionInfo pos)163 DSLExpression DSLExpression::a(PositionInfo pos) {
164     return Swizzle(std::move(*this), A, pos);
165 }
166 
field(skstd::string_view name,PositionInfo pos)167 DSLExpression DSLExpression::field(skstd::string_view name, PositionInfo pos) {
168     return DSLExpression(FieldAccess::Convert(ThreadContext::Context(),
169             *ThreadContext::SymbolTable(), this->release(), name), pos);
170 }
171 
operator =(DSLExpression right)172 DSLPossibleExpression DSLExpression::operator=(DSLExpression right) {
173     return BinaryExpression::Convert(ThreadContext::Context(), this->release(),
174             SkSL::Token::Kind::TK_EQ, right.release());
175 }
176 
operator [](DSLExpression right)177 DSLPossibleExpression DSLExpression::operator[](DSLExpression right) {
178     return IndexExpression::Convert(ThreadContext::Context(), *ThreadContext::SymbolTable(),
179             this->release(), right.release());
180 }
181 
operator ()(SkTArray<DSLWrapper<DSLExpression>> args,PositionInfo pos)182 DSLPossibleExpression DSLExpression::operator()(SkTArray<DSLWrapper<DSLExpression>> args,
183                                                 PositionInfo pos) {
184     ExpressionArray converted;
185     converted.reserve_back(args.count());
186     for (DSLWrapper<DSLExpression>& arg : args) {
187         converted.push_back(arg->release());
188     }
189     return (*this)(std::move(converted), pos);
190 }
191 
operator ()(ExpressionArray args,PositionInfo pos)192 DSLPossibleExpression DSLExpression::operator()(ExpressionArray args, PositionInfo pos) {
193     return SkSL::FunctionCall::Convert(ThreadContext::Context(), pos.line(), this->release(),
194             std::move(args));
195 }
196 
197 #define OP(op, token)                                                                              \
198 DSLPossibleExpression operator op(DSLExpression left, DSLExpression right) {                       \
199     return BinaryExpression::Convert(ThreadContext::Context(), left.release(),                     \
200             SkSL::Token::Kind::token, right.release());                                            \
201 }
202 
203 #define PREFIXOP(op, token)                                                                        \
204 DSLPossibleExpression operator op(DSLExpression expr) {                                            \
205     return PrefixExpression::Convert(ThreadContext::Context(), SkSL::Token::Kind::token,           \
206             expr.release());                                                                       \
207 }
208 
209 #define POSTFIXOP(op, token)                                                                       \
210 DSLPossibleExpression operator op(DSLExpression expr, int) {                                       \
211     return PostfixExpression::Convert(ThreadContext::Context(), expr.release(),                    \
212             SkSL::Token::Kind::token);                                                             \
213 }
214 
215 OP(+, TK_PLUS)
216 OP(+=, TK_PLUSEQ)
217 OP(-, TK_MINUS)
218 OP(-=, TK_MINUSEQ)
219 OP(*, TK_STAR)
220 OP(*=, TK_STAREQ)
221 OP(/, TK_SLASH)
222 OP(/=, TK_SLASHEQ)
223 OP(%, TK_PERCENT)
224 OP(%=, TK_PERCENTEQ)
225 OP(<<, TK_SHL)
226 OP(<<=, TK_SHLEQ)
227 OP(>>, TK_SHR)
228 OP(>>=, TK_SHREQ)
229 OP(&&, TK_LOGICALAND)
230 OP(||, TK_LOGICALOR)
231 OP(&, TK_BITWISEAND)
232 OP(&=, TK_BITWISEANDEQ)
233 OP(|, TK_BITWISEOR)
234 OP(|=, TK_BITWISEOREQ)
235 OP(^, TK_BITWISEXOR)
236 OP(^=, TK_BITWISEXOREQ)
LogicalXor(DSLExpression left,DSLExpression right)237 DSLPossibleExpression LogicalXor(DSLExpression left, DSLExpression right) {
238     return BinaryExpression::Convert(ThreadContext::Context(), left.release(),
239             SkSL::Token::Kind::TK_LOGICALXOR, right.release());
240 }
241 OP(==, TK_EQEQ)
242 OP(!=, TK_NEQ)
243 OP(>, TK_GT)
244 OP(<, TK_LT)
245 OP(>=, TK_GTEQ)
246 OP(<=, TK_LTEQ)
247 
248 PREFIXOP(+, TK_PLUS)
249 PREFIXOP(-, TK_MINUS)
250 PREFIXOP(!, TK_LOGICALNOT)
251 PREFIXOP(~, TK_BITWISENOT)
252 PREFIXOP(++, TK_PLUSPLUS)
253 POSTFIXOP(++, TK_PLUSPLUS)
254 PREFIXOP(--, TK_MINUSMINUS)
255 POSTFIXOP(--, TK_MINUSMINUS)
256 
operator ,(DSLExpression left,DSLExpression right)257 DSLPossibleExpression operator,(DSLExpression left, DSLExpression right) {
258     return BinaryExpression::Convert(ThreadContext::Context(), left.release(),
259             SkSL::Token::Kind::TK_COMMA, right.release());
260 }
261 
operator ,(DSLPossibleExpression left,DSLExpression right)262 DSLPossibleExpression operator,(DSLPossibleExpression left, DSLExpression right) {
263     return BinaryExpression::Convert(ThreadContext::Context(),
264             DSLExpression(std::move(left)).release(), SkSL::Token::Kind::TK_COMMA, right.release());
265 }
266 
operator ,(DSLExpression left,DSLPossibleExpression right)267 DSLPossibleExpression operator,(DSLExpression left, DSLPossibleExpression right) {
268     return BinaryExpression::Convert(ThreadContext::Context(), left.release(),
269             SkSL::Token::Kind::TK_COMMA, DSLExpression(std::move(right)).release());
270 }
271 
operator ,(DSLPossibleExpression left,DSLPossibleExpression right)272 DSLPossibleExpression operator,(DSLPossibleExpression left, DSLPossibleExpression right) {
273     return BinaryExpression::Convert(ThreadContext::Context(),
274             DSLExpression(std::move(left)).release(), SkSL::Token::Kind::TK_COMMA,
275             DSLExpression(std::move(right)).release());
276 }
277 
DSLPossibleExpression(std::unique_ptr<SkSL::Expression> expr)278 DSLPossibleExpression::DSLPossibleExpression(std::unique_ptr<SkSL::Expression> expr)
279     : fExpression(std::move(expr)) {}
280 
DSLPossibleExpression(DSLPossibleExpression && other)281 DSLPossibleExpression::DSLPossibleExpression(DSLPossibleExpression&& other)
282     : fExpression(std::move(other.fExpression)) {}
283 
~DSLPossibleExpression()284 DSLPossibleExpression::~DSLPossibleExpression() {
285     if (fExpression) {
286         // this handles incorporating the expression into the output tree
287         DSLExpression(std::move(fExpression));
288     }
289 }
290 
reportErrors(PositionInfo pos)291 void DSLPossibleExpression::reportErrors(PositionInfo pos) {
292     SkASSERT(!this->valid());
293     ThreadContext::ReportErrors(pos);
294 }
295 
type()296 DSLType DSLPossibleExpression::type() {
297     if (!this->valid()) {
298         return kVoid_Type;
299     }
300     return &fExpression->type();
301 }
302 
x(PositionInfo pos)303 DSLExpression DSLPossibleExpression::x(PositionInfo pos) {
304     return DSLExpression(this->release()).x(pos);
305 }
306 
y(PositionInfo pos)307 DSLExpression DSLPossibleExpression::y(PositionInfo pos) {
308     return DSLExpression(this->release()).y(pos);
309 }
310 
z(PositionInfo pos)311 DSLExpression DSLPossibleExpression::z(PositionInfo pos) {
312     return DSLExpression(this->release()).z(pos);
313 }
314 
w(PositionInfo pos)315 DSLExpression DSLPossibleExpression::w(PositionInfo pos) {
316     return DSLExpression(this->release()).w(pos);
317 }
318 
r(PositionInfo pos)319 DSLExpression DSLPossibleExpression::r(PositionInfo pos) {
320     return DSLExpression(this->release()).r(pos);
321 }
322 
g(PositionInfo pos)323 DSLExpression DSLPossibleExpression::g(PositionInfo pos) {
324     return DSLExpression(this->release()).g(pos);
325 }
326 
b(PositionInfo pos)327 DSLExpression DSLPossibleExpression::b(PositionInfo pos) {
328     return DSLExpression(this->release()).b(pos);
329 }
330 
a(PositionInfo pos)331 DSLExpression DSLPossibleExpression::a(PositionInfo pos) {
332     return DSLExpression(this->release()).a(pos);
333 }
334 
field(skstd::string_view name,PositionInfo pos)335 DSLExpression DSLPossibleExpression::field(skstd::string_view name, PositionInfo pos) {
336     return DSLExpression(this->release()).field(name, pos);
337 }
338 
operator =(DSLExpression expr)339 DSLPossibleExpression DSLPossibleExpression::operator=(DSLExpression expr) {
340     return DSLExpression(this->release()) = std::move(expr);
341 }
342 
operator =(int expr)343 DSLPossibleExpression DSLPossibleExpression::operator=(int expr) {
344     return this->operator=(DSLExpression(expr));
345 }
346 
operator =(float expr)347 DSLPossibleExpression DSLPossibleExpression::operator=(float expr) {
348     return this->operator=(DSLExpression(expr));
349 }
350 
operator =(double expr)351 DSLPossibleExpression DSLPossibleExpression::operator=(double expr) {
352     return this->operator=(DSLExpression(expr));
353 }
354 
operator [](DSLExpression index)355 DSLPossibleExpression DSLPossibleExpression::operator[](DSLExpression index) {
356     return DSLExpression(this->release())[std::move(index)];
357 }
358 
operator ()(SkTArray<DSLWrapper<DSLExpression>> args,PositionInfo pos)359 DSLPossibleExpression DSLPossibleExpression::operator()(SkTArray<DSLWrapper<DSLExpression>> args,
360                                                         PositionInfo pos) {
361     return DSLExpression(this->release())(std::move(args), pos);
362 }
363 
operator ()(ExpressionArray args,PositionInfo pos)364 DSLPossibleExpression DSLPossibleExpression::operator()(ExpressionArray args, PositionInfo pos) {
365     return DSLExpression(this->release())(std::move(args), pos);
366 }
367 
operator ++()368 DSLPossibleExpression DSLPossibleExpression::operator++() {
369     return ++DSLExpression(this->release());
370 }
371 
operator ++(int)372 DSLPossibleExpression DSLPossibleExpression::operator++(int) {
373     return DSLExpression(this->release())++;
374 }
375 
operator --()376 DSLPossibleExpression DSLPossibleExpression::operator--() {
377     return --DSLExpression(this->release());
378 }
379 
operator --(int)380 DSLPossibleExpression DSLPossibleExpression::operator--(int) {
381     return DSLExpression(this->release())--;
382 }
383 
release(PositionInfo pos)384 std::unique_ptr<SkSL::Expression> DSLPossibleExpression::release(PositionInfo pos) {
385     return DSLExpression(std::move(*this), pos).release();
386 }
387 
388 } // namespace dsl
389 
390 } // namespace SkSL
391