1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2020 Google LLC. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "src/sksl/SkSLRehydrator.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include <memory> 11cb93a386Sopenharmony_ci#include <unordered_set> 12cb93a386Sopenharmony_ci 13cb93a386Sopenharmony_ci#include "include/private/SkSLModifiers.h" 14cb93a386Sopenharmony_ci#include "include/private/SkSLProgramElement.h" 15cb93a386Sopenharmony_ci#include "include/private/SkSLStatement.h" 16cb93a386Sopenharmony_ci#include "src/sksl/SkSLAnalysis.h" 17cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLBinaryExpression.h" 18cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLBreakStatement.h" 19cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLConstructor.h" 20cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLConstructorArray.h" 21cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLConstructorCompound.h" 22cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLConstructorCompoundCast.h" 23cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLConstructorDiagonalMatrix.h" 24cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLConstructorMatrixResize.h" 25cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLConstructorScalarCast.h" 26cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLConstructorSplat.h" 27cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLConstructorStruct.h" 28cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLContinueStatement.h" 29cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLDiscardStatement.h" 30cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLDoStatement.h" 31cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLExpression.h" 32cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLExpressionStatement.h" 33cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLField.h" 34cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLFieldAccess.h" 35cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLForStatement.h" 36cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLFunctionCall.h" 37cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLFunctionDeclaration.h" 38cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLFunctionDefinition.h" 39cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLIfStatement.h" 40cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLIndexExpression.h" 41cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLInlineMarker.h" 42cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLInterfaceBlock.h" 43cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLLiteral.h" 44cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLPostfixExpression.h" 45cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLPrefixExpression.h" 46cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLReturnStatement.h" 47cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLSetting.h" 48cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLStructDefinition.h" 49cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLSwitchCase.h" 50cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLSwitchStatement.h" 51cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLSwizzle.h" 52cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLSymbolAlias.h" 53cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLSymbolTable.h" 54cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLTernaryExpression.h" 55cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLType.h" 56cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLUnresolvedFunction.h" 57cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLVarDeclarations.h" 58cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLVariable.h" 59cb93a386Sopenharmony_ci 60cb93a386Sopenharmony_cinamespace SkSL { 61cb93a386Sopenharmony_ci 62cb93a386Sopenharmony_ciclass AutoRehydratorSymbolTable { 63cb93a386Sopenharmony_cipublic: 64cb93a386Sopenharmony_ci AutoRehydratorSymbolTable(Rehydrator* rehydrator) 65cb93a386Sopenharmony_ci : fRehydrator(rehydrator) 66cb93a386Sopenharmony_ci , fOldSymbols(fRehydrator->fSymbolTable) { 67cb93a386Sopenharmony_ci fRehydrator->fSymbolTable = fRehydrator->symbolTable(); 68cb93a386Sopenharmony_ci } 69cb93a386Sopenharmony_ci 70cb93a386Sopenharmony_ci ~AutoRehydratorSymbolTable() { 71cb93a386Sopenharmony_ci fRehydrator->fSymbolTable = std::move(fOldSymbols); 72cb93a386Sopenharmony_ci } 73cb93a386Sopenharmony_ci 74cb93a386Sopenharmony_ciprivate: 75cb93a386Sopenharmony_ci Rehydrator* fRehydrator; 76cb93a386Sopenharmony_ci std::shared_ptr<SymbolTable> fOldSymbols; 77cb93a386Sopenharmony_ci}; 78cb93a386Sopenharmony_ci 79cb93a386Sopenharmony_ciRehydrator::Rehydrator(const Context* context, std::shared_ptr<SymbolTable> symbolTable, 80cb93a386Sopenharmony_ci const uint8_t* src, size_t length) 81cb93a386Sopenharmony_ci : fContext(*context) 82cb93a386Sopenharmony_ci , fSymbolTable(std::move(symbolTable)) 83cb93a386Sopenharmony_ci , fStart(src) 84cb93a386Sopenharmony_ci SkDEBUGCODE(, fEnd(fStart + length)) { 85cb93a386Sopenharmony_ci SkASSERT(fSymbolTable); 86cb93a386Sopenharmony_ci SkASSERT(fSymbolTable->isBuiltin()); 87cb93a386Sopenharmony_ci // skip past string data 88cb93a386Sopenharmony_ci fIP = fStart; 89cb93a386Sopenharmony_ci fIP += this->readU16(); 90cb93a386Sopenharmony_ci} 91cb93a386Sopenharmony_ci 92cb93a386Sopenharmony_ciLayout Rehydrator::layout() { 93cb93a386Sopenharmony_ci switch (this->readU8()) { 94cb93a386Sopenharmony_ci case kBuiltinLayout_Command: { 95cb93a386Sopenharmony_ci Layout result; 96cb93a386Sopenharmony_ci result.fBuiltin = this->readS16(); 97cb93a386Sopenharmony_ci return result; 98cb93a386Sopenharmony_ci } 99cb93a386Sopenharmony_ci case kDefaultLayout_Command: 100cb93a386Sopenharmony_ci return Layout(); 101cb93a386Sopenharmony_ci case kLayout_Command: { 102cb93a386Sopenharmony_ci int flags = this->readU32(); 103cb93a386Sopenharmony_ci int location = this->readS8(); 104cb93a386Sopenharmony_ci int offset = this->readS8(); 105cb93a386Sopenharmony_ci int binding = this->readS8(); 106cb93a386Sopenharmony_ci int index = this->readS8(); 107cb93a386Sopenharmony_ci int set = this->readS8(); 108cb93a386Sopenharmony_ci int builtin = this->readS16(); 109cb93a386Sopenharmony_ci int inputAttachmentIndex = this->readS8(); 110cb93a386Sopenharmony_ci return Layout( 111cb93a386Sopenharmony_ci flags, location, offset, binding, index, set, builtin, inputAttachmentIndex); 112cb93a386Sopenharmony_ci } 113cb93a386Sopenharmony_ci default: 114cb93a386Sopenharmony_ci SkASSERT(false); 115cb93a386Sopenharmony_ci return Layout(); 116cb93a386Sopenharmony_ci } 117cb93a386Sopenharmony_ci} 118cb93a386Sopenharmony_ci 119cb93a386Sopenharmony_ciModifiers Rehydrator::modifiers() { 120cb93a386Sopenharmony_ci switch (this->readU8()) { 121cb93a386Sopenharmony_ci case kDefaultModifiers_Command: 122cb93a386Sopenharmony_ci return Modifiers(); 123cb93a386Sopenharmony_ci case kModifiers8Bit_Command: { 124cb93a386Sopenharmony_ci Layout l = this->layout(); 125cb93a386Sopenharmony_ci int flags = this->readU8(); 126cb93a386Sopenharmony_ci return Modifiers(l, flags); 127cb93a386Sopenharmony_ci } 128cb93a386Sopenharmony_ci case kModifiers_Command: { 129cb93a386Sopenharmony_ci Layout l = this->layout(); 130cb93a386Sopenharmony_ci int flags = this->readS32(); 131cb93a386Sopenharmony_ci return Modifiers(l, flags); 132cb93a386Sopenharmony_ci } 133cb93a386Sopenharmony_ci default: 134cb93a386Sopenharmony_ci SkASSERT(false); 135cb93a386Sopenharmony_ci return Modifiers(); 136cb93a386Sopenharmony_ci } 137cb93a386Sopenharmony_ci} 138cb93a386Sopenharmony_ci 139cb93a386Sopenharmony_ciconst Symbol* Rehydrator::symbol() { 140cb93a386Sopenharmony_ci int kind = this->readU8(); 141cb93a386Sopenharmony_ci switch (kind) { 142cb93a386Sopenharmony_ci case kArrayType_Command: { 143cb93a386Sopenharmony_ci uint16_t id = this->readU16(); 144cb93a386Sopenharmony_ci const Type* componentType = this->type(); 145cb93a386Sopenharmony_ci int8_t count = this->readS8(); 146cb93a386Sopenharmony_ci const String* arrayName = 147cb93a386Sopenharmony_ci fSymbolTable->takeOwnershipOfString(componentType->getArrayName(count)); 148cb93a386Sopenharmony_ci const Type* result = fSymbolTable->takeOwnershipOfSymbol( 149cb93a386Sopenharmony_ci Type::MakeArrayType(*arrayName, *componentType, count)); 150cb93a386Sopenharmony_ci this->addSymbol(id, result); 151cb93a386Sopenharmony_ci return result; 152cb93a386Sopenharmony_ci } 153cb93a386Sopenharmony_ci case kFunctionDeclaration_Command: { 154cb93a386Sopenharmony_ci uint16_t id = this->readU16(); 155cb93a386Sopenharmony_ci Modifiers modifiers = this->modifiers(); 156cb93a386Sopenharmony_ci skstd::string_view name = this->readString(); 157cb93a386Sopenharmony_ci int parameterCount = this->readU8(); 158cb93a386Sopenharmony_ci std::vector<const Variable*> parameters; 159cb93a386Sopenharmony_ci parameters.reserve(parameterCount); 160cb93a386Sopenharmony_ci for (int i = 0; i < parameterCount; ++i) { 161cb93a386Sopenharmony_ci parameters.push_back(this->symbolRef<Variable>(Symbol::Kind::kVariable)); 162cb93a386Sopenharmony_ci } 163cb93a386Sopenharmony_ci const Type* returnType = this->type(); 164cb93a386Sopenharmony_ci const FunctionDeclaration* result = 165cb93a386Sopenharmony_ci fSymbolTable->takeOwnershipOfSymbol(std::make_unique<FunctionDeclaration>( 166cb93a386Sopenharmony_ci /*line=*/-1, 167cb93a386Sopenharmony_ci this->modifiersPool().add(modifiers), 168cb93a386Sopenharmony_ci name, 169cb93a386Sopenharmony_ci std::move(parameters), 170cb93a386Sopenharmony_ci returnType, 171cb93a386Sopenharmony_ci /*builtin=*/true)); 172cb93a386Sopenharmony_ci this->addSymbol(id, result); 173cb93a386Sopenharmony_ci return result; 174cb93a386Sopenharmony_ci } 175cb93a386Sopenharmony_ci case kField_Command: { 176cb93a386Sopenharmony_ci const Variable* owner = this->symbolRef<Variable>(Symbol::Kind::kVariable); 177cb93a386Sopenharmony_ci uint8_t index = this->readU8(); 178cb93a386Sopenharmony_ci const Field* result = fSymbolTable->takeOwnershipOfSymbol( 179cb93a386Sopenharmony_ci std::make_unique<Field>(/*line=*/-1, owner, index)); 180cb93a386Sopenharmony_ci return result; 181cb93a386Sopenharmony_ci } 182cb93a386Sopenharmony_ci case kStructType_Command: { 183cb93a386Sopenharmony_ci uint16_t id = this->readU16(); 184cb93a386Sopenharmony_ci String name(this->readString()); 185cb93a386Sopenharmony_ci uint8_t fieldCount = this->readU8(); 186cb93a386Sopenharmony_ci std::vector<Type::Field> fields; 187cb93a386Sopenharmony_ci fields.reserve(fieldCount); 188cb93a386Sopenharmony_ci for (int i = 0; i < fieldCount; ++i) { 189cb93a386Sopenharmony_ci Modifiers m = this->modifiers(); 190cb93a386Sopenharmony_ci skstd::string_view fieldName = this->readString(); 191cb93a386Sopenharmony_ci const Type* type = this->type(); 192cb93a386Sopenharmony_ci fields.emplace_back(m, fieldName, type); 193cb93a386Sopenharmony_ci } 194cb93a386Sopenharmony_ci skstd::string_view nameChars(*fSymbolTable->takeOwnershipOfString(std::move(name))); 195cb93a386Sopenharmony_ci const Type* result = fSymbolTable->takeOwnershipOfSymbol( 196cb93a386Sopenharmony_ci Type::MakeStructType(/*line=*/-1, nameChars, std::move(fields))); 197cb93a386Sopenharmony_ci this->addSymbol(id, result); 198cb93a386Sopenharmony_ci return result; 199cb93a386Sopenharmony_ci } 200cb93a386Sopenharmony_ci case kSymbolRef_Command: { 201cb93a386Sopenharmony_ci uint16_t id = this->readU16(); 202cb93a386Sopenharmony_ci SkASSERT(fSymbols.size() > id); 203cb93a386Sopenharmony_ci return fSymbols[id]; 204cb93a386Sopenharmony_ci } 205cb93a386Sopenharmony_ci case kSymbolAlias_Command: { 206cb93a386Sopenharmony_ci uint16_t id = this->readU16(); 207cb93a386Sopenharmony_ci skstd::string_view name = this->readString(); 208cb93a386Sopenharmony_ci const Symbol* origSymbol = this->symbol(); 209cb93a386Sopenharmony_ci const SymbolAlias* symbolAlias = fSymbolTable->takeOwnershipOfSymbol( 210cb93a386Sopenharmony_ci std::make_unique<SymbolAlias>(/*line=*/-1, name, origSymbol)); 211cb93a386Sopenharmony_ci this->addSymbol(id, symbolAlias); 212cb93a386Sopenharmony_ci return symbolAlias; 213cb93a386Sopenharmony_ci } 214cb93a386Sopenharmony_ci case kSystemType_Command: { 215cb93a386Sopenharmony_ci uint16_t id = this->readU16(); 216cb93a386Sopenharmony_ci skstd::string_view name = this->readString(); 217cb93a386Sopenharmony_ci const Symbol* result = (*fSymbolTable)[name]; 218cb93a386Sopenharmony_ci SkASSERT(result && result->kind() == Symbol::Kind::kType); 219cb93a386Sopenharmony_ci this->addSymbol(id, result); 220cb93a386Sopenharmony_ci return result; 221cb93a386Sopenharmony_ci } 222cb93a386Sopenharmony_ci case kUnresolvedFunction_Command: { 223cb93a386Sopenharmony_ci uint16_t id = this->readU16(); 224cb93a386Sopenharmony_ci int length = this->readU8(); 225cb93a386Sopenharmony_ci std::vector<const FunctionDeclaration*> functions; 226cb93a386Sopenharmony_ci functions.reserve(length); 227cb93a386Sopenharmony_ci for (int i = 0; i < length; ++i) { 228cb93a386Sopenharmony_ci const Symbol* f = this->symbol(); 229cb93a386Sopenharmony_ci SkASSERT(f && f->kind() == Symbol::Kind::kFunctionDeclaration); 230cb93a386Sopenharmony_ci functions.push_back((const FunctionDeclaration*) f); 231cb93a386Sopenharmony_ci } 232cb93a386Sopenharmony_ci const UnresolvedFunction* result = fSymbolTable->takeOwnershipOfSymbol( 233cb93a386Sopenharmony_ci std::make_unique<UnresolvedFunction>(std::move(functions))); 234cb93a386Sopenharmony_ci this->addSymbol(id, result); 235cb93a386Sopenharmony_ci return result; 236cb93a386Sopenharmony_ci } 237cb93a386Sopenharmony_ci case kVariable_Command: { 238cb93a386Sopenharmony_ci uint16_t id = this->readU16(); 239cb93a386Sopenharmony_ci const Modifiers* m = this->modifiersPool().add(this->modifiers()); 240cb93a386Sopenharmony_ci skstd::string_view name = this->readString(); 241cb93a386Sopenharmony_ci const Type* type = this->type(); 242cb93a386Sopenharmony_ci Variable::Storage storage = (Variable::Storage) this->readU8(); 243cb93a386Sopenharmony_ci const Variable* result = fSymbolTable->takeOwnershipOfSymbol(std::make_unique<Variable>( 244cb93a386Sopenharmony_ci /*line=*/-1, m, name, type, /*builtin=*/true, storage)); 245cb93a386Sopenharmony_ci this->addSymbol(id, result); 246cb93a386Sopenharmony_ci return result; 247cb93a386Sopenharmony_ci } 248cb93a386Sopenharmony_ci default: 249cb93a386Sopenharmony_ci printf("unsupported symbol %d\n", kind); 250cb93a386Sopenharmony_ci SkASSERT(false); 251cb93a386Sopenharmony_ci return nullptr; 252cb93a386Sopenharmony_ci } 253cb93a386Sopenharmony_ci} 254cb93a386Sopenharmony_ci 255cb93a386Sopenharmony_ciconst Type* Rehydrator::type() { 256cb93a386Sopenharmony_ci const Symbol* result = this->symbol(); 257cb93a386Sopenharmony_ci SkASSERT(result->kind() == Symbol::Kind::kType); 258cb93a386Sopenharmony_ci return (const Type*) result; 259cb93a386Sopenharmony_ci} 260cb93a386Sopenharmony_ci 261cb93a386Sopenharmony_cistd::vector<std::unique_ptr<ProgramElement>> Rehydrator::elements() { 262cb93a386Sopenharmony_ci SkDEBUGCODE(uint8_t command = )this->readU8(); 263cb93a386Sopenharmony_ci SkASSERT(command == kElements_Command); 264cb93a386Sopenharmony_ci std::vector<std::unique_ptr<ProgramElement>> result; 265cb93a386Sopenharmony_ci while (std::unique_ptr<ProgramElement> elem = this->element()) { 266cb93a386Sopenharmony_ci result.push_back(std::move(elem)); 267cb93a386Sopenharmony_ci } 268cb93a386Sopenharmony_ci return result; 269cb93a386Sopenharmony_ci} 270cb93a386Sopenharmony_ci 271cb93a386Sopenharmony_cistd::unique_ptr<ProgramElement> Rehydrator::element() { 272cb93a386Sopenharmony_ci int kind = this->readU8(); 273cb93a386Sopenharmony_ci switch (kind) { 274cb93a386Sopenharmony_ci case Rehydrator::kFunctionDefinition_Command: { 275cb93a386Sopenharmony_ci const FunctionDeclaration* decl = this->symbolRef<FunctionDeclaration>( 276cb93a386Sopenharmony_ci Symbol::Kind::kFunctionDeclaration); 277cb93a386Sopenharmony_ci std::unique_ptr<Statement> body = this->statement(); 278cb93a386Sopenharmony_ci auto result = FunctionDefinition::Convert(fContext, /*line=*/-1, *decl, 279cb93a386Sopenharmony_ci std::move(body), /*builtin=*/true); 280cb93a386Sopenharmony_ci decl->setDefinition(result.get()); 281cb93a386Sopenharmony_ci return std::move(result); 282cb93a386Sopenharmony_ci } 283cb93a386Sopenharmony_ci case Rehydrator::kInterfaceBlock_Command: { 284cb93a386Sopenharmony_ci const Symbol* var = this->symbol(); 285cb93a386Sopenharmony_ci SkASSERT(var && var->is<Variable>()); 286cb93a386Sopenharmony_ci skstd::string_view typeName = this->readString(); 287cb93a386Sopenharmony_ci skstd::string_view instanceName = this->readString(); 288cb93a386Sopenharmony_ci int arraySize = this->readS8(); 289cb93a386Sopenharmony_ci return std::make_unique<InterfaceBlock>(/*line=*/-1, var->as<Variable>(), typeName, 290cb93a386Sopenharmony_ci instanceName, arraySize, nullptr); 291cb93a386Sopenharmony_ci } 292cb93a386Sopenharmony_ci case Rehydrator::kVarDeclarations_Command: { 293cb93a386Sopenharmony_ci std::unique_ptr<Statement> decl = this->statement(); 294cb93a386Sopenharmony_ci return std::make_unique<GlobalVarDeclaration>(std::move(decl)); 295cb93a386Sopenharmony_ci } 296cb93a386Sopenharmony_ci case Rehydrator::kStructDefinition_Command: { 297cb93a386Sopenharmony_ci const Symbol* type = this->symbol(); 298cb93a386Sopenharmony_ci SkASSERT(type && type->is<Type>()); 299cb93a386Sopenharmony_ci return std::make_unique<StructDefinition>(/*line=*/-1, type->as<Type>()); 300cb93a386Sopenharmony_ci } 301cb93a386Sopenharmony_ci case Rehydrator::kElementsComplete_Command: 302cb93a386Sopenharmony_ci return nullptr; 303cb93a386Sopenharmony_ci default: 304cb93a386Sopenharmony_ci SkDEBUGFAILF("unsupported element %d\n", kind); 305cb93a386Sopenharmony_ci return nullptr; 306cb93a386Sopenharmony_ci } 307cb93a386Sopenharmony_ci} 308cb93a386Sopenharmony_ci 309cb93a386Sopenharmony_cistd::unique_ptr<Statement> Rehydrator::statement() { 310cb93a386Sopenharmony_ci int kind = this->readU8(); 311cb93a386Sopenharmony_ci switch (kind) { 312cb93a386Sopenharmony_ci case Rehydrator::kBlock_Command: { 313cb93a386Sopenharmony_ci AutoRehydratorSymbolTable symbols(this); 314cb93a386Sopenharmony_ci int count = this->readU8(); 315cb93a386Sopenharmony_ci StatementArray statements; 316cb93a386Sopenharmony_ci statements.reserve_back(count); 317cb93a386Sopenharmony_ci for (int i = 0; i < count; ++i) { 318cb93a386Sopenharmony_ci statements.push_back(this->statement()); 319cb93a386Sopenharmony_ci } 320cb93a386Sopenharmony_ci bool isScope = this->readU8(); 321cb93a386Sopenharmony_ci return Block::Make(/*line=*/-1, std::move(statements), fSymbolTable, isScope); 322cb93a386Sopenharmony_ci } 323cb93a386Sopenharmony_ci case Rehydrator::kBreak_Command: 324cb93a386Sopenharmony_ci return BreakStatement::Make(/*line=*/-1); 325cb93a386Sopenharmony_ci case Rehydrator::kContinue_Command: 326cb93a386Sopenharmony_ci return ContinueStatement::Make(/*line=*/-1); 327cb93a386Sopenharmony_ci case Rehydrator::kDiscard_Command: 328cb93a386Sopenharmony_ci return DiscardStatement::Make(/*line=*/-1); 329cb93a386Sopenharmony_ci case Rehydrator::kDo_Command: { 330cb93a386Sopenharmony_ci std::unique_ptr<Statement> stmt = this->statement(); 331cb93a386Sopenharmony_ci std::unique_ptr<Expression> expr = this->expression(); 332cb93a386Sopenharmony_ci return DoStatement::Make(fContext, std::move(stmt), std::move(expr)); 333cb93a386Sopenharmony_ci } 334cb93a386Sopenharmony_ci case Rehydrator::kExpressionStatement_Command: { 335cb93a386Sopenharmony_ci std::unique_ptr<Expression> expr = this->expression(); 336cb93a386Sopenharmony_ci return ExpressionStatement::Make(fContext, std::move(expr)); 337cb93a386Sopenharmony_ci } 338cb93a386Sopenharmony_ci case Rehydrator::kFor_Command: { 339cb93a386Sopenharmony_ci std::unique_ptr<Statement> initializer = this->statement(); 340cb93a386Sopenharmony_ci std::unique_ptr<Expression> test = this->expression(); 341cb93a386Sopenharmony_ci std::unique_ptr<Expression> next = this->expression(); 342cb93a386Sopenharmony_ci std::unique_ptr<Statement> body = this->statement(); 343cb93a386Sopenharmony_ci std::shared_ptr<SymbolTable> symbols = this->symbolTable(); 344cb93a386Sopenharmony_ci std::unique_ptr<LoopUnrollInfo> unrollInfo = 345cb93a386Sopenharmony_ci Analysis::GetLoopUnrollInfo(/*line=*/-1, initializer.get(), test.get(), 346cb93a386Sopenharmony_ci next.get(), body.get(), /*errors=*/nullptr); 347cb93a386Sopenharmony_ci return ForStatement::Make(fContext, /*line=*/-1, std::move(initializer), 348cb93a386Sopenharmony_ci std::move(test), std::move(next), std::move(body), 349cb93a386Sopenharmony_ci std::move(unrollInfo), std::move(symbols)); 350cb93a386Sopenharmony_ci } 351cb93a386Sopenharmony_ci case Rehydrator::kIf_Command: { 352cb93a386Sopenharmony_ci bool isStatic = this->readU8(); 353cb93a386Sopenharmony_ci std::unique_ptr<Expression> test = this->expression(); 354cb93a386Sopenharmony_ci std::unique_ptr<Statement> ifTrue = this->statement(); 355cb93a386Sopenharmony_ci std::unique_ptr<Statement> ifFalse = this->statement(); 356cb93a386Sopenharmony_ci return IfStatement::Make(fContext, /*line=*/-1, isStatic, std::move(test), 357cb93a386Sopenharmony_ci std::move(ifTrue), std::move(ifFalse)); 358cb93a386Sopenharmony_ci } 359cb93a386Sopenharmony_ci case Rehydrator::kInlineMarker_Command: { 360cb93a386Sopenharmony_ci const FunctionDeclaration* funcDecl = this->symbolRef<FunctionDeclaration>( 361cb93a386Sopenharmony_ci Symbol::Kind::kFunctionDeclaration); 362cb93a386Sopenharmony_ci return InlineMarker::Make(funcDecl); 363cb93a386Sopenharmony_ci } 364cb93a386Sopenharmony_ci case Rehydrator::kReturn_Command: { 365cb93a386Sopenharmony_ci std::unique_ptr<Expression> expr = this->expression(); 366cb93a386Sopenharmony_ci return ReturnStatement::Make(/*line=*/-1, std::move(expr)); 367cb93a386Sopenharmony_ci } 368cb93a386Sopenharmony_ci case Rehydrator::kSwitch_Command: { 369cb93a386Sopenharmony_ci bool isStatic = this->readU8(); 370cb93a386Sopenharmony_ci AutoRehydratorSymbolTable symbols(this); 371cb93a386Sopenharmony_ci std::unique_ptr<Expression> expr = this->expression(); 372cb93a386Sopenharmony_ci int caseCount = this->readU8(); 373cb93a386Sopenharmony_ci StatementArray cases; 374cb93a386Sopenharmony_ci cases.reserve_back(caseCount); 375cb93a386Sopenharmony_ci for (int i = 0; i < caseCount; ++i) { 376cb93a386Sopenharmony_ci std::unique_ptr<Expression> value = this->expression(); 377cb93a386Sopenharmony_ci std::unique_ptr<Statement> statement = this->statement(); 378cb93a386Sopenharmony_ci cases.push_back(std::make_unique<SwitchCase>(/*line=*/-1, std::move(value), 379cb93a386Sopenharmony_ci std::move(statement))); 380cb93a386Sopenharmony_ci } 381cb93a386Sopenharmony_ci return SwitchStatement::Make(fContext, /*line=*/-1, isStatic, std::move(expr), 382cb93a386Sopenharmony_ci std::move(cases), fSymbolTable); 383cb93a386Sopenharmony_ci } 384cb93a386Sopenharmony_ci case Rehydrator::kVarDeclaration_Command: { 385cb93a386Sopenharmony_ci Variable* var = this->symbolRef<Variable>(Symbol::Kind::kVariable); 386cb93a386Sopenharmony_ci const Type* baseType = this->type(); 387cb93a386Sopenharmony_ci int arraySize = this->readS8(); 388cb93a386Sopenharmony_ci std::unique_ptr<Expression> value = this->expression(); 389cb93a386Sopenharmony_ci return VarDeclaration::Make(fContext, var, baseType, arraySize, std::move(value)); 390cb93a386Sopenharmony_ci } 391cb93a386Sopenharmony_ci case Rehydrator::kVoid_Command: 392cb93a386Sopenharmony_ci return nullptr; 393cb93a386Sopenharmony_ci default: 394cb93a386Sopenharmony_ci printf("unsupported statement %d\n", kind); 395cb93a386Sopenharmony_ci SkASSERT(false); 396cb93a386Sopenharmony_ci return nullptr; 397cb93a386Sopenharmony_ci } 398cb93a386Sopenharmony_ci} 399cb93a386Sopenharmony_ci 400cb93a386Sopenharmony_ciExpressionArray Rehydrator::expressionArray() { 401cb93a386Sopenharmony_ci uint8_t count = this->readU8(); 402cb93a386Sopenharmony_ci ExpressionArray array; 403cb93a386Sopenharmony_ci array.reserve_back(count); 404cb93a386Sopenharmony_ci for (int i = 0; i < count; ++i) { 405cb93a386Sopenharmony_ci array.push_back(this->expression()); 406cb93a386Sopenharmony_ci } 407cb93a386Sopenharmony_ci return array; 408cb93a386Sopenharmony_ci} 409cb93a386Sopenharmony_ci 410cb93a386Sopenharmony_cistd::unique_ptr<Expression> Rehydrator::expression() { 411cb93a386Sopenharmony_ci int kind = this->readU8(); 412cb93a386Sopenharmony_ci switch (kind) { 413cb93a386Sopenharmony_ci case Rehydrator::kBinary_Command: { 414cb93a386Sopenharmony_ci std::unique_ptr<Expression> left = this->expression(); 415cb93a386Sopenharmony_ci Token::Kind op = (Token::Kind) this->readU8(); 416cb93a386Sopenharmony_ci std::unique_ptr<Expression> right = this->expression(); 417cb93a386Sopenharmony_ci return BinaryExpression::Make(fContext, std::move(left), op, std::move(right)); 418cb93a386Sopenharmony_ci } 419cb93a386Sopenharmony_ci case Rehydrator::kBoolLiteral_Command: { 420cb93a386Sopenharmony_ci bool value = this->readU8(); 421cb93a386Sopenharmony_ci return Literal::MakeBool(fContext, /*line=*/-1, value); 422cb93a386Sopenharmony_ci } 423cb93a386Sopenharmony_ci case Rehydrator::kConstructorArray_Command: { 424cb93a386Sopenharmony_ci const Type* type = this->type(); 425cb93a386Sopenharmony_ci return ConstructorArray::Make(fContext, /*line=*/-1, *type, this->expressionArray()); 426cb93a386Sopenharmony_ci } 427cb93a386Sopenharmony_ci case Rehydrator::kConstructorCompound_Command: { 428cb93a386Sopenharmony_ci const Type* type = this->type(); 429cb93a386Sopenharmony_ci return ConstructorCompound::Make(fContext, /*line=*/-1, *type, 430cb93a386Sopenharmony_ci this->expressionArray()); 431cb93a386Sopenharmony_ci } 432cb93a386Sopenharmony_ci case Rehydrator::kConstructorDiagonalMatrix_Command: { 433cb93a386Sopenharmony_ci const Type* type = this->type(); 434cb93a386Sopenharmony_ci ExpressionArray args = this->expressionArray(); 435cb93a386Sopenharmony_ci SkASSERT(args.size() == 1); 436cb93a386Sopenharmony_ci return ConstructorDiagonalMatrix::Make(fContext, /*line=*/-1, *type, 437cb93a386Sopenharmony_ci std::move(args[0])); 438cb93a386Sopenharmony_ci } 439cb93a386Sopenharmony_ci case Rehydrator::kConstructorMatrixResize_Command: { 440cb93a386Sopenharmony_ci const Type* type = this->type(); 441cb93a386Sopenharmony_ci ExpressionArray args = this->expressionArray(); 442cb93a386Sopenharmony_ci SkASSERT(args.size() == 1); 443cb93a386Sopenharmony_ci return ConstructorMatrixResize::Make(fContext, /*line=*/-1, *type, 444cb93a386Sopenharmony_ci std::move(args[0])); 445cb93a386Sopenharmony_ci } 446cb93a386Sopenharmony_ci case Rehydrator::kConstructorScalarCast_Command: { 447cb93a386Sopenharmony_ci const Type* type = this->type(); 448cb93a386Sopenharmony_ci ExpressionArray args = this->expressionArray(); 449cb93a386Sopenharmony_ci SkASSERT(args.size() == 1); 450cb93a386Sopenharmony_ci return ConstructorScalarCast::Make(fContext, /*line=*/-1, *type, std::move(args[0])); 451cb93a386Sopenharmony_ci } 452cb93a386Sopenharmony_ci case Rehydrator::kConstructorSplat_Command: { 453cb93a386Sopenharmony_ci const Type* type = this->type(); 454cb93a386Sopenharmony_ci ExpressionArray args = this->expressionArray(); 455cb93a386Sopenharmony_ci SkASSERT(args.size() == 1); 456cb93a386Sopenharmony_ci return ConstructorSplat::Make(fContext, /*line=*/-1, *type, std::move(args[0])); 457cb93a386Sopenharmony_ci } 458cb93a386Sopenharmony_ci case Rehydrator::kConstructorStruct_Command: { 459cb93a386Sopenharmony_ci const Type* type = this->type(); 460cb93a386Sopenharmony_ci return ConstructorStruct::Make(fContext, /*line=*/-1, *type, this->expressionArray()); 461cb93a386Sopenharmony_ci } 462cb93a386Sopenharmony_ci case Rehydrator::kConstructorCompoundCast_Command: { 463cb93a386Sopenharmony_ci const Type* type = this->type(); 464cb93a386Sopenharmony_ci ExpressionArray args = this->expressionArray(); 465cb93a386Sopenharmony_ci SkASSERT(args.size() == 1); 466cb93a386Sopenharmony_ci return ConstructorCompoundCast::Make(fContext,/*line=*/-1, *type, std::move(args[0])); 467cb93a386Sopenharmony_ci } 468cb93a386Sopenharmony_ci case Rehydrator::kFieldAccess_Command: { 469cb93a386Sopenharmony_ci std::unique_ptr<Expression> base = this->expression(); 470cb93a386Sopenharmony_ci int index = this->readU8(); 471cb93a386Sopenharmony_ci FieldAccess::OwnerKind ownerKind = (FieldAccess::OwnerKind) this->readU8(); 472cb93a386Sopenharmony_ci return FieldAccess::Make(fContext, std::move(base), index, ownerKind); 473cb93a386Sopenharmony_ci } 474cb93a386Sopenharmony_ci case Rehydrator::kFloatLiteral_Command: { 475cb93a386Sopenharmony_ci const Type* type = this->type(); 476cb93a386Sopenharmony_ci int32_t floatBits = this->readS32(); 477cb93a386Sopenharmony_ci float value; 478cb93a386Sopenharmony_ci memcpy(&value, &floatBits, sizeof(value)); 479cb93a386Sopenharmony_ci return Literal::MakeFloat(/*line=*/-1, value, type); 480cb93a386Sopenharmony_ci } 481cb93a386Sopenharmony_ci case Rehydrator::kFunctionCall_Command: { 482cb93a386Sopenharmony_ci const Type* type = this->type(); 483cb93a386Sopenharmony_ci const FunctionDeclaration* f = this->symbolRef<FunctionDeclaration>( 484cb93a386Sopenharmony_ci Symbol::Kind::kFunctionDeclaration); 485cb93a386Sopenharmony_ci ExpressionArray args = this->expressionArray(); 486cb93a386Sopenharmony_ci return FunctionCall::Make(fContext, /*line=*/-1, type, *f, std::move(args)); 487cb93a386Sopenharmony_ci } 488cb93a386Sopenharmony_ci case Rehydrator::kIndex_Command: { 489cb93a386Sopenharmony_ci std::unique_ptr<Expression> base = this->expression(); 490cb93a386Sopenharmony_ci std::unique_ptr<Expression> index = this->expression(); 491cb93a386Sopenharmony_ci return IndexExpression::Make(fContext, std::move(base), std::move(index)); 492cb93a386Sopenharmony_ci } 493cb93a386Sopenharmony_ci case Rehydrator::kIntLiteral_Command: { 494cb93a386Sopenharmony_ci const Type* type = this->type(); 495cb93a386Sopenharmony_ci int value = this->readS32(); 496cb93a386Sopenharmony_ci return Literal::MakeInt(/*line=*/-1, value, type); 497cb93a386Sopenharmony_ci } 498cb93a386Sopenharmony_ci case Rehydrator::kPostfix_Command: { 499cb93a386Sopenharmony_ci Token::Kind op = (Token::Kind) this->readU8(); 500cb93a386Sopenharmony_ci std::unique_ptr<Expression> operand = this->expression(); 501cb93a386Sopenharmony_ci return PostfixExpression::Make(fContext, std::move(operand), op); 502cb93a386Sopenharmony_ci } 503cb93a386Sopenharmony_ci case Rehydrator::kPrefix_Command: { 504cb93a386Sopenharmony_ci Token::Kind op = (Token::Kind) this->readU8(); 505cb93a386Sopenharmony_ci std::unique_ptr<Expression> operand = this->expression(); 506cb93a386Sopenharmony_ci return PrefixExpression::Make(fContext, op, std::move(operand)); 507cb93a386Sopenharmony_ci } 508cb93a386Sopenharmony_ci case Rehydrator::kSetting_Command: { 509cb93a386Sopenharmony_ci String name(this->readString()); 510cb93a386Sopenharmony_ci return Setting::Convert(fContext, /*line=*/-1, name); 511cb93a386Sopenharmony_ci } 512cb93a386Sopenharmony_ci case Rehydrator::kSwizzle_Command: { 513cb93a386Sopenharmony_ci std::unique_ptr<Expression> base = this->expression(); 514cb93a386Sopenharmony_ci int count = this->readU8(); 515cb93a386Sopenharmony_ci ComponentArray components; 516cb93a386Sopenharmony_ci for (int i = 0; i < count; ++i) { 517cb93a386Sopenharmony_ci components.push_back(this->readU8()); 518cb93a386Sopenharmony_ci } 519cb93a386Sopenharmony_ci return Swizzle::Make(fContext, std::move(base), components); 520cb93a386Sopenharmony_ci } 521cb93a386Sopenharmony_ci case Rehydrator::kTernary_Command: { 522cb93a386Sopenharmony_ci std::unique_ptr<Expression> test = this->expression(); 523cb93a386Sopenharmony_ci std::unique_ptr<Expression> ifTrue = this->expression(); 524cb93a386Sopenharmony_ci std::unique_ptr<Expression> ifFalse = this->expression(); 525cb93a386Sopenharmony_ci return TernaryExpression::Make(fContext, std::move(test), 526cb93a386Sopenharmony_ci std::move(ifTrue), std::move(ifFalse)); 527cb93a386Sopenharmony_ci } 528cb93a386Sopenharmony_ci case Rehydrator::kVariableReference_Command: { 529cb93a386Sopenharmony_ci const Variable* var = this->symbolRef<Variable>(Symbol::Kind::kVariable); 530cb93a386Sopenharmony_ci VariableReference::RefKind refKind = (VariableReference::RefKind) this->readU8(); 531cb93a386Sopenharmony_ci return VariableReference::Make(/*line=*/-1, var, refKind); 532cb93a386Sopenharmony_ci } 533cb93a386Sopenharmony_ci case Rehydrator::kVoid_Command: 534cb93a386Sopenharmony_ci return nullptr; 535cb93a386Sopenharmony_ci default: 536cb93a386Sopenharmony_ci printf("unsupported expression %d\n", kind); 537cb93a386Sopenharmony_ci SkASSERT(false); 538cb93a386Sopenharmony_ci return nullptr; 539cb93a386Sopenharmony_ci } 540cb93a386Sopenharmony_ci} 541cb93a386Sopenharmony_ci 542cb93a386Sopenharmony_cistd::shared_ptr<SymbolTable> Rehydrator::symbolTable(bool inherit) { 543cb93a386Sopenharmony_ci int command = this->readU8(); 544cb93a386Sopenharmony_ci if (command == kVoid_Command) { 545cb93a386Sopenharmony_ci return nullptr; 546cb93a386Sopenharmony_ci } 547cb93a386Sopenharmony_ci SkASSERT(command == kSymbolTable_Command); 548cb93a386Sopenharmony_ci uint16_t ownedCount = this->readU16(); 549cb93a386Sopenharmony_ci std::shared_ptr<SymbolTable> oldTable = fSymbolTable; 550cb93a386Sopenharmony_ci std::shared_ptr<SymbolTable> result = 551cb93a386Sopenharmony_ci inherit ? std::make_shared<SymbolTable>(fSymbolTable, /*builtin=*/true) 552cb93a386Sopenharmony_ci : std::make_shared<SymbolTable>(fContext, /*builtin=*/true); 553cb93a386Sopenharmony_ci fSymbolTable = result; 554cb93a386Sopenharmony_ci std::vector<const Symbol*> ownedSymbols; 555cb93a386Sopenharmony_ci ownedSymbols.reserve(ownedCount); 556cb93a386Sopenharmony_ci for (int i = 0; i < ownedCount; ++i) { 557cb93a386Sopenharmony_ci ownedSymbols.push_back(this->symbol()); 558cb93a386Sopenharmony_ci } 559cb93a386Sopenharmony_ci uint16_t symbolCount = this->readU16(); 560cb93a386Sopenharmony_ci std::vector<std::pair<skstd::string_view, int>> symbols; 561cb93a386Sopenharmony_ci symbols.reserve(symbolCount); 562cb93a386Sopenharmony_ci for (int i = 0; i < symbolCount; ++i) { 563cb93a386Sopenharmony_ci int index = this->readU16(); 564cb93a386Sopenharmony_ci fSymbolTable->addWithoutOwnership(ownedSymbols[index]); 565cb93a386Sopenharmony_ci } 566cb93a386Sopenharmony_ci fSymbolTable = oldTable; 567cb93a386Sopenharmony_ci return result; 568cb93a386Sopenharmony_ci} 569cb93a386Sopenharmony_ci 570cb93a386Sopenharmony_ci} // namespace SkSL 571