1 /*
2 * Copyright 2018 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 #ifndef SKSL_STANDALONE
9
10 #include "SkSLInterpreter.h"
11 #include "ir/SkSLBinaryExpression.h"
12 #include "ir/SkSLExpressionStatement.h"
13 #include "ir/SkSLForStatement.h"
14 #include "ir/SkSLFunctionCall.h"
15 #include "ir/SkSLFunctionReference.h"
16 #include "ir/SkSLIfStatement.h"
17 #include "ir/SkSLIndexExpression.h"
18 #include "ir/SkSLPostfixExpression.h"
19 #include "ir/SkSLPrefixExpression.h"
20 #include "ir/SkSLProgram.h"
21 #include "ir/SkSLStatement.h"
22 #include "ir/SkSLTernaryExpression.h"
23 #include "ir/SkSLVarDeclarations.h"
24 #include "ir/SkSLVarDeclarationsStatement.h"
25 #include "ir/SkSLVariableReference.h"
26 #include "SkRasterPipeline.h"
27
28 namespace SkSL {
29
run()30 void Interpreter::run() {
31 for (const auto& e : *fProgram) {
32 if (ProgramElement::kFunction_Kind == e.fKind) {
33 const FunctionDefinition& f = (const FunctionDefinition&) e;
34 if ("appendStages" == f.fDeclaration.fName) {
35 this->run(f);
36 return;
37 }
38 }
39 }
40 SkASSERT(false);
41 }
42
SizeOf(const Type & type)43 static int SizeOf(const Type& type) {
44 return 1;
45 }
46
run(const FunctionDefinition & f)47 void Interpreter::run(const FunctionDefinition& f) {
48 fVars.emplace_back();
49 StackIndex current = (StackIndex) fStack.size();
50 for (int i = f.fDeclaration.fParameters.size() - 1; i >= 0; --i) {
51 current -= SizeOf(f.fDeclaration.fParameters[i]->fType);
52 fVars.back()[f.fDeclaration.fParameters[i]] = current;
53 }
54 fCurrentIndex.push_back({ f.fBody.get(), 0 });
55 while (fCurrentIndex.size()) {
56 this->runStatement();
57 }
58 }
59
push(Value value)60 void Interpreter::push(Value value) {
61 fStack.push_back(value);
62 }
63
pop()64 Interpreter::Value Interpreter::pop() {
65 auto iter = fStack.end() - 1;
66 Value result = *iter;
67 fStack.erase(iter);
68 return result;
69 }
70
stackAlloc(int count)71 Interpreter::StackIndex Interpreter::stackAlloc(int count) {
72 int result = fStack.size();
73 for (int i = 0; i < count; ++i) {
74 fStack.push_back(Value((int) 0xDEADBEEF));
75 }
76 return result;
77 }
78
runStatement()79 void Interpreter::runStatement() {
80 const Statement& stmt = *fCurrentIndex.back().fStatement;
81 const size_t index = fCurrentIndex.back().fIndex;
82 fCurrentIndex.pop_back();
83 switch (stmt.fKind) {
84 case Statement::kBlock_Kind: {
85 const Block& b = (const Block&) stmt;
86 if (!b.fStatements.size()) {
87 break;
88 }
89 SkASSERT(index < b.fStatements.size());
90 if (index < b.fStatements.size() - 1) {
91 fCurrentIndex.push_back({ &b, index + 1 });
92 }
93 fCurrentIndex.push_back({ b.fStatements[index].get(), 0 });
94 break;
95 }
96 case Statement::kBreak_Kind:
97 SkASSERT(index == 0);
98 abort();
99 case Statement::kContinue_Kind:
100 SkASSERT(index == 0);
101 abort();
102 case Statement::kDiscard_Kind:
103 SkASSERT(index == 0);
104 abort();
105 case Statement::kDo_Kind:
106 abort();
107 case Statement::kExpression_Kind:
108 SkASSERT(index == 0);
109 this->evaluate(*((const ExpressionStatement&) stmt).fExpression);
110 break;
111 case Statement::kFor_Kind: {
112 ForStatement& f = (ForStatement&) stmt;
113 switch (index) {
114 case 0:
115 // initializer
116 fCurrentIndex.push_back({ &f, 1 });
117 if (f.fInitializer) {
118 fCurrentIndex.push_back({ f.fInitializer.get(), 0 });
119 }
120 break;
121 case 1:
122 // test & body
123 if (f.fTest && !evaluate(*f.fTest).fBool) {
124 break;
125 } else {
126 fCurrentIndex.push_back({ &f, 2 });
127 fCurrentIndex.push_back({ f.fStatement.get(), 0 });
128 }
129 break;
130 case 2:
131 // next
132 if (f.fNext) {
133 this->evaluate(*f.fNext);
134 }
135 fCurrentIndex.push_back({ &f, 1 });
136 break;
137 default:
138 SkASSERT(false);
139 }
140 break;
141 }
142 case Statement::kGroup_Kind:
143 abort();
144 case Statement::kIf_Kind: {
145 IfStatement& i = (IfStatement&) stmt;
146 if (evaluate(*i.fTest).fBool) {
147 fCurrentIndex.push_back({ i.fIfTrue.get(), 0 });
148 } else if (i.fIfFalse) {
149 fCurrentIndex.push_back({ i.fIfFalse.get(), 0 });
150 }
151 break;
152 }
153 case Statement::kNop_Kind:
154 SkASSERT(index == 0);
155 break;
156 case Statement::kReturn_Kind:
157 SkASSERT(index == 0);
158 abort();
159 case Statement::kSwitch_Kind:
160 abort();
161 case Statement::kVarDeclarations_Kind:
162 SkASSERT(index == 0);
163 for (const auto& decl :((const VarDeclarationsStatement&) stmt).fDeclaration->fVars) {
164 const Variable* var = ((VarDeclaration&) *decl).fVar;
165 StackIndex pos = this->stackAlloc(SizeOf(var->fType));
166 fVars.back()[var] = pos;
167 if (var->fInitialValue) {
168 fStack[pos] = this->evaluate(*var->fInitialValue);
169 }
170 }
171 break;
172 case Statement::kWhile_Kind:
173 abort();
174 default:
175 abort();
176 }
177 }
178
type_kind(const Type & type)179 static Interpreter::TypeKind type_kind(const Type& type) {
180 if (type.fName == "int") {
181 return Interpreter::kInt_TypeKind;
182 } else if (type.fName == "float") {
183 return Interpreter::kFloat_TypeKind;
184 }
185 ABORT("unsupported type: %s\n", type.description().c_str());
186 }
187
getLValue(const Expression & expr)188 Interpreter::StackIndex Interpreter::getLValue(const Expression& expr) {
189 switch (expr.fKind) {
190 case Expression::kFieldAccess_Kind:
191 break;
192 case Expression::kIndex_Kind: {
193 const IndexExpression& idx = (const IndexExpression&) expr;
194 return this->evaluate(*idx.fBase).fInt + this->evaluate(*idx.fIndex).fInt;
195 }
196 case Expression::kSwizzle_Kind:
197 break;
198 case Expression::kVariableReference_Kind:
199 SkASSERT(fVars.size());
200 SkASSERT(fVars.back().find(&((VariableReference&) expr).fVariable) !=
201 fVars.back().end());
202 return fVars.back()[&((VariableReference&) expr).fVariable];
203 case Expression::kTernary_Kind: {
204 const TernaryExpression& t = (const TernaryExpression&) expr;
205 return this->getLValue(this->evaluate(*t.fTest).fBool ? *t.fIfTrue : *t.fIfFalse);
206 }
207 case Expression::kTypeReference_Kind:
208 break;
209 default:
210 break;
211 }
212 ABORT("unsupported lvalue");
213 }
214
215 struct CallbackCtx : public SkRasterPipeline_CallbackCtx {
216 Interpreter* fInterpreter;
217 const FunctionDefinition* fFunction;
218 };
219
do_callback(SkRasterPipeline_CallbackCtx * raw,int activePixels)220 static void do_callback(SkRasterPipeline_CallbackCtx* raw, int activePixels) {
221 CallbackCtx& ctx = (CallbackCtx&) *raw;
222 for (int i = 0; i < activePixels; ++i) {
223 ctx.fInterpreter->push(Interpreter::Value(ctx.rgba[i * 4 + 0]));
224 ctx.fInterpreter->push(Interpreter::Value(ctx.rgba[i * 4 + 1]));
225 ctx.fInterpreter->push(Interpreter::Value(ctx.rgba[i * 4 + 2]));
226 ctx.fInterpreter->run(*ctx.fFunction);
227 ctx.read_from[i * 4 + 2] = ctx.fInterpreter->pop().fFloat;
228 ctx.read_from[i * 4 + 1] = ctx.fInterpreter->pop().fFloat;
229 ctx.read_from[i * 4 + 0] = ctx.fInterpreter->pop().fFloat;
230 }
231 }
232
appendStage(const AppendStage & a)233 void Interpreter::appendStage(const AppendStage& a) {
234 switch (a.fStage) {
235 case SkRasterPipeline::matrix_4x5: {
236 SkASSERT(a.fArguments.size() == 1);
237 StackIndex transpose = evaluate(*a.fArguments[0]).fInt;
238 fPipeline.append(SkRasterPipeline::matrix_4x5, &fStack[transpose]);
239 break;
240 }
241 case SkRasterPipeline::callback: {
242 SkASSERT(a.fArguments.size() == 1);
243 CallbackCtx* ctx = new CallbackCtx();
244 ctx->fInterpreter = this;
245 ctx->fn = do_callback;
246 for (const auto& e : *fProgram) {
247 if (ProgramElement::kFunction_Kind == e.fKind) {
248 const FunctionDefinition& f = (const FunctionDefinition&) e;
249 if (&f.fDeclaration ==
250 ((const FunctionReference&) *a.fArguments[0]).fFunctions[0]) {
251 ctx->fFunction = &f;
252 }
253 }
254 }
255 fPipeline.append(SkRasterPipeline::callback, ctx);
256 break;
257 }
258 default:
259 fPipeline.append(a.fStage);
260 }
261 }
262
call(const FunctionCall & c)263 Interpreter::Value Interpreter::call(const FunctionCall& c) {
264 abort();
265 }
266
evaluate(const Expression & expr)267 Interpreter::Value Interpreter::evaluate(const Expression& expr) {
268 switch (expr.fKind) {
269 case Expression::kAppendStage_Kind:
270 this->appendStage((const AppendStage&) expr);
271 return Value((int) 0xDEADBEEF);
272 case Expression::kBinary_Kind: {
273 #define ARITHMETIC(op) { \
274 Value left = this->evaluate(*b.fLeft); \
275 Value right = this->evaluate(*b.fRight); \
276 switch (type_kind(b.fLeft->fType)) { \
277 case kFloat_TypeKind: \
278 return Value(left.fFloat op right.fFloat); \
279 case kInt_TypeKind: \
280 return Value(left.fInt op right.fInt); \
281 default: \
282 abort(); \
283 } \
284 }
285 #define BITWISE(op) { \
286 Value left = this->evaluate(*b.fLeft); \
287 Value right = this->evaluate(*b.fRight); \
288 switch (type_kind(b.fLeft->fType)) { \
289 case kInt_TypeKind: \
290 return Value(left.fInt op right.fInt); \
291 default: \
292 abort(); \
293 } \
294 }
295 #define LOGIC(op) { \
296 Value left = this->evaluate(*b.fLeft); \
297 Value right = this->evaluate(*b.fRight); \
298 switch (type_kind(b.fLeft->fType)) { \
299 case kFloat_TypeKind: \
300 return Value(left.fFloat op right.fFloat); \
301 case kInt_TypeKind: \
302 return Value(left.fInt op right.fInt); \
303 default: \
304 abort(); \
305 } \
306 }
307 #define COMPOUND_ARITHMETIC(op) { \
308 StackIndex left = this->getLValue(*b.fLeft); \
309 Value right = this->evaluate(*b.fRight); \
310 Value result = fStack[left]; \
311 switch (type_kind(b.fLeft->fType)) { \
312 case kFloat_TypeKind: \
313 result.fFloat op right.fFloat; \
314 break; \
315 case kInt_TypeKind: \
316 result.fInt op right.fInt; \
317 break; \
318 default: \
319 abort(); \
320 } \
321 fStack[left] = result; \
322 return result; \
323 }
324 #define COMPOUND_BITWISE(op) { \
325 StackIndex left = this->getLValue(*b.fLeft); \
326 Value right = this->evaluate(*b.fRight); \
327 Value result = fStack[left]; \
328 switch (type_kind(b.fLeft->fType)) { \
329 case kInt_TypeKind: \
330 result.fInt op right.fInt; \
331 break; \
332 default: \
333 abort(); \
334 } \
335 fStack[left] = result; \
336 return result; \
337 }
338 const BinaryExpression& b = (const BinaryExpression&) expr;
339 switch (b.fOperator) {
340 case Token::PLUS: ARITHMETIC(+)
341 case Token::MINUS: ARITHMETIC(-)
342 case Token::STAR: ARITHMETIC(*)
343 case Token::SLASH: ARITHMETIC(/)
344 case Token::BITWISEAND: BITWISE(&)
345 case Token::BITWISEOR: BITWISE(|)
346 case Token::BITWISEXOR: BITWISE(^)
347 case Token::LT: LOGIC(<)
348 case Token::GT: LOGIC(>)
349 case Token::LTEQ: LOGIC(<=)
350 case Token::GTEQ: LOGIC(>=)
351 case Token::LOGICALAND: {
352 Value result = this->evaluate(*b.fLeft);
353 if (result.fBool) {
354 result = this->evaluate(*b.fRight);
355 }
356 return result;
357 }
358 case Token::LOGICALOR: {
359 Value result = this->evaluate(*b.fLeft);
360 if (!result.fBool) {
361 result = this->evaluate(*b.fRight);
362 }
363 return result;
364 }
365 case Token::EQ: {
366 StackIndex left = this->getLValue(*b.fLeft);
367 Value right = this->evaluate(*b.fRight);
368 fStack[left] = right;
369 return right;
370 }
371 case Token::PLUSEQ: COMPOUND_ARITHMETIC(+=)
372 case Token::MINUSEQ: COMPOUND_ARITHMETIC(-=)
373 case Token::STAREQ: COMPOUND_ARITHMETIC(*=)
374 case Token::SLASHEQ: COMPOUND_ARITHMETIC(/=)
375 case Token::BITWISEANDEQ: COMPOUND_BITWISE(&=)
376 case Token::BITWISEOREQ: COMPOUND_BITWISE(|=)
377 case Token::BITWISEXOREQ: COMPOUND_BITWISE(^=)
378 default:
379 ABORT("unsupported operator: %s\n", expr.description().c_str());
380 }
381 break;
382 }
383 case Expression::kBoolLiteral_Kind:
384 return Value(((const BoolLiteral&) expr).fValue);
385 case Expression::kConstructor_Kind:
386 break;
387 case Expression::kIntLiteral_Kind:
388 return Value((int) ((const IntLiteral&) expr).fValue);
389 case Expression::kFieldAccess_Kind:
390 break;
391 case Expression::kFloatLiteral_Kind:
392 return Value((float) ((const FloatLiteral&) expr).fValue);
393 case Expression::kFunctionCall_Kind:
394 return this->call((const FunctionCall&) expr);
395 case Expression::kIndex_Kind: {
396 const IndexExpression& idx = (const IndexExpression&) expr;
397 StackIndex pos = this->evaluate(*idx.fBase).fInt +
398 this->evaluate(*idx.fIndex).fInt;
399 return fStack[pos];
400 }
401 case Expression::kPrefix_Kind: {
402 const PrefixExpression& p = (const PrefixExpression&) expr;
403 switch (p.fOperator) {
404 case Token::MINUS: {
405 Value base = this->evaluate(*p.fOperand);
406 switch (type_kind(p.fType)) {
407 case kFloat_TypeKind:
408 return Value(-base.fFloat);
409 case kInt_TypeKind:
410 return Value(-base.fInt);
411 default:
412 abort();
413 }
414 }
415 case Token::LOGICALNOT: {
416 Value base = this->evaluate(*p.fOperand);
417 return Value(!base.fBool);
418 }
419 default:
420 abort();
421 }
422 }
423 case Expression::kPostfix_Kind: {
424 const PostfixExpression& p = (const PostfixExpression&) expr;
425 StackIndex lvalue = this->getLValue(*p.fOperand);
426 Value result = fStack[lvalue];
427 switch (type_kind(p.fType)) {
428 case kFloat_TypeKind:
429 if (Token::PLUSPLUS == p.fOperator) {
430 ++fStack[lvalue].fFloat;
431 } else {
432 SkASSERT(Token::MINUSMINUS == p.fOperator);
433 --fStack[lvalue].fFloat;
434 }
435 break;
436 case kInt_TypeKind:
437 if (Token::PLUSPLUS == p.fOperator) {
438 ++fStack[lvalue].fInt;
439 } else {
440 SkASSERT(Token::MINUSMINUS == p.fOperator);
441 --fStack[lvalue].fInt;
442 }
443 break;
444 default:
445 abort();
446 }
447 return result;
448 }
449 case Expression::kSetting_Kind:
450 break;
451 case Expression::kSwizzle_Kind:
452 break;
453 case Expression::kVariableReference_Kind:
454 SkASSERT(fVars.size());
455 SkASSERT(fVars.back().find(&((VariableReference&) expr).fVariable) !=
456 fVars.back().end());
457 return fStack[fVars.back()[&((VariableReference&) expr).fVariable]];
458 case Expression::kTernary_Kind: {
459 const TernaryExpression& t = (const TernaryExpression&) expr;
460 return this->evaluate(this->evaluate(*t.fTest).fBool ? *t.fIfTrue : *t.fIfFalse);
461 }
462 case Expression::kTypeReference_Kind:
463 break;
464 default:
465 break;
466 }
467 ABORT("unsupported expression: %s\n", expr.description().c_str());
468 }
469
470 } // namespace
471
472 #endif
473