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 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 43 static int SizeOf(const Type& type) { 44 return 1; 45 } 46 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 60 void Interpreter::push(Value value) { 61 fStack.push_back(value); 62 } 63 64 Interpreter::Value Interpreter::pop() { 65 auto iter = fStack.end() - 1; 66 Value result = *iter; 67 fStack.erase(iter); 68 return result; 69 } 70 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 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 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 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 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 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 263 Interpreter::Value Interpreter::call(const FunctionCall& c) { 264 abort(); 265 } 266 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