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