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/SkSLDehydrator.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include <map> 11cb93a386Sopenharmony_ci 12cb93a386Sopenharmony_ci#include "include/private/SkSLProgramElement.h" 13cb93a386Sopenharmony_ci#include "include/private/SkSLStatement.h" 14cb93a386Sopenharmony_ci#include "include/private/SkSLSymbol.h" 15cb93a386Sopenharmony_ci#include "src/sksl/SkSLRehydrator.h" 16cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLBinaryExpression.h" 17cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLBreakStatement.h" 18cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLConstructor.h" 19cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLConstructorArray.h" 20cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLConstructorArrayCast.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/SkSLExpressionStatement.h" 32cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLField.h" 33cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLFieldAccess.h" 34cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLForStatement.h" 35cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLFunctionCall.h" 36cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLFunctionDeclaration.h" 37cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLFunctionDefinition.h" 38cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLIfStatement.h" 39cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLIndexExpression.h" 40cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLInlineMarker.h" 41cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLInterfaceBlock.h" 42cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLLiteral.h" 43cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLPostfixExpression.h" 44cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLPrefixExpression.h" 45cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLReturnStatement.h" 46cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLSetting.h" 47cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLStructDefinition.h" 48cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLSwitchCase.h" 49cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLSwitchStatement.h" 50cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLSwizzle.h" 51cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLSymbolAlias.h" 52cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLSymbolTable.h" 53cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLTernaryExpression.h" 54cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLUnresolvedFunction.h" 55cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLVarDeclarations.h" 56cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLVariable.h" 57cb93a386Sopenharmony_ci 58cb93a386Sopenharmony_ci#ifdef SKSL_STANDALONE 59cb93a386Sopenharmony_ci 60cb93a386Sopenharmony_cinamespace SkSL { 61cb93a386Sopenharmony_ci 62cb93a386Sopenharmony_cistatic constexpr int HEADER_SIZE = 2; 63cb93a386Sopenharmony_ci 64cb93a386Sopenharmony_ciclass AutoDehydratorSymbolTable { 65cb93a386Sopenharmony_cipublic: 66cb93a386Sopenharmony_ci AutoDehydratorSymbolTable(Dehydrator* dehydrator, const std::shared_ptr<SymbolTable>& symbols) 67cb93a386Sopenharmony_ci : fDehydrator(dehydrator) { 68cb93a386Sopenharmony_ci dehydrator->fSymbolMap.emplace_back(); 69cb93a386Sopenharmony_ci if (symbols) { 70cb93a386Sopenharmony_ci dehydrator->write(*symbols); 71cb93a386Sopenharmony_ci } else { 72cb93a386Sopenharmony_ci dehydrator->writeCommand(Rehydrator::kVoid_Command); 73cb93a386Sopenharmony_ci } 74cb93a386Sopenharmony_ci } 75cb93a386Sopenharmony_ci 76cb93a386Sopenharmony_ci ~AutoDehydratorSymbolTable() { 77cb93a386Sopenharmony_ci fDehydrator->fSymbolMap.pop_back(); 78cb93a386Sopenharmony_ci } 79cb93a386Sopenharmony_ci 80cb93a386Sopenharmony_ciprivate: 81cb93a386Sopenharmony_ci Dehydrator* fDehydrator; 82cb93a386Sopenharmony_ci}; 83cb93a386Sopenharmony_ci 84cb93a386Sopenharmony_civoid Dehydrator::write(Layout l) { 85cb93a386Sopenharmony_ci if (l == Layout()) { 86cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kDefaultLayout_Command); 87cb93a386Sopenharmony_ci } else if (l == Layout::builtin(l.fBuiltin)) { 88cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kBuiltinLayout_Command); 89cb93a386Sopenharmony_ci this->writeS16(l.fBuiltin); 90cb93a386Sopenharmony_ci } else { 91cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kLayout_Command); 92cb93a386Sopenharmony_ci fBody.write32(l.fFlags); 93cb93a386Sopenharmony_ci this->writeS8(l.fLocation); 94cb93a386Sopenharmony_ci this->writeS8(l.fOffset); 95cb93a386Sopenharmony_ci this->writeS8(l.fBinding); 96cb93a386Sopenharmony_ci this->writeS8(l.fIndex); 97cb93a386Sopenharmony_ci this->writeS8(l.fSet); 98cb93a386Sopenharmony_ci this->writeS16(l.fBuiltin); 99cb93a386Sopenharmony_ci this->writeS8(l.fInputAttachmentIndex); 100cb93a386Sopenharmony_ci } 101cb93a386Sopenharmony_ci} 102cb93a386Sopenharmony_ci 103cb93a386Sopenharmony_civoid Dehydrator::write(Modifiers m) { 104cb93a386Sopenharmony_ci if (m == Modifiers()) { 105cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kDefaultModifiers_Command); 106cb93a386Sopenharmony_ci } else { 107cb93a386Sopenharmony_ci if (m.fFlags <= 255) { 108cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kModifiers8Bit_Command); 109cb93a386Sopenharmony_ci this->write(m.fLayout); 110cb93a386Sopenharmony_ci this->writeU8(m.fFlags); 111cb93a386Sopenharmony_ci } else { 112cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kModifiers_Command); 113cb93a386Sopenharmony_ci this->write(m.fLayout); 114cb93a386Sopenharmony_ci this->writeS32(m.fFlags); 115cb93a386Sopenharmony_ci } 116cb93a386Sopenharmony_ci } 117cb93a386Sopenharmony_ci} 118cb93a386Sopenharmony_ci 119cb93a386Sopenharmony_civoid Dehydrator::write(skstd::string_view s) { 120cb93a386Sopenharmony_ci this->write(String(s)); 121cb93a386Sopenharmony_ci} 122cb93a386Sopenharmony_ci 123cb93a386Sopenharmony_civoid Dehydrator::write(String s) { 124cb93a386Sopenharmony_ci auto found = fStrings.find(s); 125cb93a386Sopenharmony_ci int offset; 126cb93a386Sopenharmony_ci if (found == fStrings.end()) { 127cb93a386Sopenharmony_ci offset = fStringBuffer.str().length() + HEADER_SIZE; 128cb93a386Sopenharmony_ci fStrings.insert({ s, offset }); 129cb93a386Sopenharmony_ci SkASSERT(s.length() <= 255); 130cb93a386Sopenharmony_ci fStringBreaks.add(fStringBuffer.bytesWritten()); 131cb93a386Sopenharmony_ci fStringBuffer.write8(s.length()); 132cb93a386Sopenharmony_ci fStringBuffer.writeString(s); 133cb93a386Sopenharmony_ci } else { 134cb93a386Sopenharmony_ci offset = found->second; 135cb93a386Sopenharmony_ci } 136cb93a386Sopenharmony_ci this->writeU16(offset); 137cb93a386Sopenharmony_ci} 138cb93a386Sopenharmony_ci 139cb93a386Sopenharmony_civoid Dehydrator::write(const Symbol& s) { 140cb93a386Sopenharmony_ci uint16_t id = this->symbolId(&s, false); 141cb93a386Sopenharmony_ci if (id) { 142cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kSymbolRef_Command); 143cb93a386Sopenharmony_ci this->writeU16(id); 144cb93a386Sopenharmony_ci return; 145cb93a386Sopenharmony_ci } 146cb93a386Sopenharmony_ci switch (s.kind()) { 147cb93a386Sopenharmony_ci case Symbol::Kind::kFunctionDeclaration: { 148cb93a386Sopenharmony_ci const FunctionDeclaration& f = s.as<FunctionDeclaration>(); 149cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kFunctionDeclaration_Command); 150cb93a386Sopenharmony_ci this->writeId(&f); 151cb93a386Sopenharmony_ci this->write(f.modifiers()); 152cb93a386Sopenharmony_ci this->write(f.name()); 153cb93a386Sopenharmony_ci this->writeU8(f.parameters().size()); 154cb93a386Sopenharmony_ci for (const Variable* p : f.parameters()) { 155cb93a386Sopenharmony_ci this->writeU16(this->symbolId(p)); 156cb93a386Sopenharmony_ci } 157cb93a386Sopenharmony_ci this->write(f.returnType()); 158cb93a386Sopenharmony_ci break; 159cb93a386Sopenharmony_ci } 160cb93a386Sopenharmony_ci case Symbol::Kind::kSymbolAlias: { 161cb93a386Sopenharmony_ci const SymbolAlias& alias = s.as<SymbolAlias>(); 162cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kSymbolAlias_Command); 163cb93a386Sopenharmony_ci this->writeId(&alias); 164cb93a386Sopenharmony_ci this->write(alias.name()); 165cb93a386Sopenharmony_ci this->write(*alias.origSymbol()); 166cb93a386Sopenharmony_ci break; 167cb93a386Sopenharmony_ci } 168cb93a386Sopenharmony_ci case Symbol::Kind::kUnresolvedFunction: { 169cb93a386Sopenharmony_ci const UnresolvedFunction& f = s.as<UnresolvedFunction>(); 170cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kUnresolvedFunction_Command); 171cb93a386Sopenharmony_ci this->writeId(&f); 172cb93a386Sopenharmony_ci this->writeU8(f.functions().size()); 173cb93a386Sopenharmony_ci for (const FunctionDeclaration* funcDecl : f.functions()) { 174cb93a386Sopenharmony_ci this->write(*funcDecl); 175cb93a386Sopenharmony_ci } 176cb93a386Sopenharmony_ci break; 177cb93a386Sopenharmony_ci } 178cb93a386Sopenharmony_ci case Symbol::Kind::kType: { 179cb93a386Sopenharmony_ci const Type& t = s.as<Type>(); 180cb93a386Sopenharmony_ci switch (t.typeKind()) { 181cb93a386Sopenharmony_ci case Type::TypeKind::kArray: 182cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kArrayType_Command); 183cb93a386Sopenharmony_ci this->writeId(&t); 184cb93a386Sopenharmony_ci this->write(t.componentType()); 185cb93a386Sopenharmony_ci this->writeS8(t.columns()); 186cb93a386Sopenharmony_ci break; 187cb93a386Sopenharmony_ci case Type::TypeKind::kStruct: 188cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kStructType_Command); 189cb93a386Sopenharmony_ci this->writeId(&t); 190cb93a386Sopenharmony_ci this->write(t.name()); 191cb93a386Sopenharmony_ci this->writeU8(t.fields().size()); 192cb93a386Sopenharmony_ci for (const Type::Field& f : t.fields()) { 193cb93a386Sopenharmony_ci this->write(f.fModifiers); 194cb93a386Sopenharmony_ci this->write(f.fName); 195cb93a386Sopenharmony_ci this->write(*f.fType); 196cb93a386Sopenharmony_ci } 197cb93a386Sopenharmony_ci break; 198cb93a386Sopenharmony_ci default: 199cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kSystemType_Command); 200cb93a386Sopenharmony_ci this->writeId(&t); 201cb93a386Sopenharmony_ci this->write(t.name()); 202cb93a386Sopenharmony_ci break; 203cb93a386Sopenharmony_ci } 204cb93a386Sopenharmony_ci break; 205cb93a386Sopenharmony_ci } 206cb93a386Sopenharmony_ci case Symbol::Kind::kVariable: { 207cb93a386Sopenharmony_ci const Variable& v = s.as<Variable>(); 208cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kVariable_Command); 209cb93a386Sopenharmony_ci this->writeId(&v); 210cb93a386Sopenharmony_ci this->write(v.modifiers()); 211cb93a386Sopenharmony_ci this->write(v.name()); 212cb93a386Sopenharmony_ci this->write(v.type()); 213cb93a386Sopenharmony_ci this->writeU8((int8_t) v.storage()); 214cb93a386Sopenharmony_ci break; 215cb93a386Sopenharmony_ci } 216cb93a386Sopenharmony_ci case Symbol::Kind::kField: { 217cb93a386Sopenharmony_ci const Field& f = s.as<Field>(); 218cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kField_Command); 219cb93a386Sopenharmony_ci this->writeU16(this->symbolId(&f.owner())); 220cb93a386Sopenharmony_ci this->writeU8(f.fieldIndex()); 221cb93a386Sopenharmony_ci break; 222cb93a386Sopenharmony_ci } 223cb93a386Sopenharmony_ci case Symbol::Kind::kExternal: 224cb93a386Sopenharmony_ci SkASSERT(false); 225cb93a386Sopenharmony_ci break; 226cb93a386Sopenharmony_ci } 227cb93a386Sopenharmony_ci} 228cb93a386Sopenharmony_ci 229cb93a386Sopenharmony_civoid Dehydrator::write(const SymbolTable& symbols) { 230cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kSymbolTable_Command); 231cb93a386Sopenharmony_ci this->writeU16(symbols.fOwnedSymbols.size()); 232cb93a386Sopenharmony_ci for (const std::unique_ptr<const Symbol>& s : symbols.fOwnedSymbols) { 233cb93a386Sopenharmony_ci this->write(*s); 234cb93a386Sopenharmony_ci } 235cb93a386Sopenharmony_ci this->writeU16(symbols.fSymbols.count()); 236cb93a386Sopenharmony_ci std::map<skstd::string_view, const Symbol*> ordered; 237cb93a386Sopenharmony_ci symbols.foreach([&](skstd::string_view name, const Symbol* symbol) { 238cb93a386Sopenharmony_ci ordered.insert({name, symbol}); 239cb93a386Sopenharmony_ci }); 240cb93a386Sopenharmony_ci for (std::pair<skstd::string_view, const Symbol*> p : ordered) { 241cb93a386Sopenharmony_ci SkDEBUGCODE(bool found = false;) 242cb93a386Sopenharmony_ci for (size_t i = 0; i < symbols.fOwnedSymbols.size(); ++i) { 243cb93a386Sopenharmony_ci if (symbols.fOwnedSymbols[i].get() == p.second) { 244cb93a386Sopenharmony_ci fCommandBreaks.add(fBody.bytesWritten()); 245cb93a386Sopenharmony_ci this->writeU16(i); 246cb93a386Sopenharmony_ci SkDEBUGCODE(found = true;) 247cb93a386Sopenharmony_ci break; 248cb93a386Sopenharmony_ci } 249cb93a386Sopenharmony_ci } 250cb93a386Sopenharmony_ci SkASSERT(found); 251cb93a386Sopenharmony_ci } 252cb93a386Sopenharmony_ci} 253cb93a386Sopenharmony_ci 254cb93a386Sopenharmony_civoid Dehydrator::writeExpressionSpan(const SkSpan<const std::unique_ptr<Expression>>& span) { 255cb93a386Sopenharmony_ci this->writeU8(span.size()); 256cb93a386Sopenharmony_ci for (const auto& expr : span) { 257cb93a386Sopenharmony_ci this->write(expr.get()); 258cb93a386Sopenharmony_ci } 259cb93a386Sopenharmony_ci} 260cb93a386Sopenharmony_ci 261cb93a386Sopenharmony_civoid Dehydrator::write(const Expression* e) { 262cb93a386Sopenharmony_ci if (e) { 263cb93a386Sopenharmony_ci switch (e->kind()) { 264cb93a386Sopenharmony_ci case Expression::Kind::kBinary: { 265cb93a386Sopenharmony_ci const BinaryExpression& b = e->as<BinaryExpression>(); 266cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kBinary_Command); 267cb93a386Sopenharmony_ci this->write(b.left().get()); 268cb93a386Sopenharmony_ci this->writeU8((int) b.getOperator().kind()); 269cb93a386Sopenharmony_ci this->write(b.right().get()); 270cb93a386Sopenharmony_ci break; 271cb93a386Sopenharmony_ci } 272cb93a386Sopenharmony_ci case Expression::Kind::kChildCall: 273cb93a386Sopenharmony_ci SkDEBUGFAIL("unimplemented--not expected to be used from within an include file"); 274cb93a386Sopenharmony_ci break; 275cb93a386Sopenharmony_ci 276cb93a386Sopenharmony_ci case Expression::Kind::kCodeString: 277cb93a386Sopenharmony_ci SkDEBUGFAIL("shouldn't be able to receive kCodeString here"); 278cb93a386Sopenharmony_ci break; 279cb93a386Sopenharmony_ci 280cb93a386Sopenharmony_ci case Expression::Kind::kConstructorArray: 281cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kConstructorArray_Command); 282cb93a386Sopenharmony_ci this->write(e->type()); 283cb93a386Sopenharmony_ci this->writeExpressionSpan(e->as<ConstructorArray>().argumentSpan()); 284cb93a386Sopenharmony_ci break; 285cb93a386Sopenharmony_ci 286cb93a386Sopenharmony_ci case Expression::Kind::kConstructorArrayCast: 287cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kConstructorArrayCast_Command); 288cb93a386Sopenharmony_ci this->write(e->type()); 289cb93a386Sopenharmony_ci this->writeExpressionSpan(e->as<ConstructorArrayCast>().argumentSpan()); 290cb93a386Sopenharmony_ci break; 291cb93a386Sopenharmony_ci 292cb93a386Sopenharmony_ci case Expression::Kind::kConstructorCompound: 293cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kConstructorCompound_Command); 294cb93a386Sopenharmony_ci this->write(e->type()); 295cb93a386Sopenharmony_ci this->writeExpressionSpan(e->as<ConstructorCompound>().argumentSpan()); 296cb93a386Sopenharmony_ci break; 297cb93a386Sopenharmony_ci 298cb93a386Sopenharmony_ci case Expression::Kind::kConstructorCompoundCast: 299cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kConstructorCompoundCast_Command); 300cb93a386Sopenharmony_ci this->write(e->type()); 301cb93a386Sopenharmony_ci this->writeExpressionSpan(e->as<ConstructorCompoundCast>().argumentSpan()); 302cb93a386Sopenharmony_ci break; 303cb93a386Sopenharmony_ci 304cb93a386Sopenharmony_ci case Expression::Kind::kConstructorDiagonalMatrix: 305cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kConstructorDiagonalMatrix_Command); 306cb93a386Sopenharmony_ci this->write(e->type()); 307cb93a386Sopenharmony_ci this->writeExpressionSpan(e->as<ConstructorDiagonalMatrix>().argumentSpan()); 308cb93a386Sopenharmony_ci break; 309cb93a386Sopenharmony_ci 310cb93a386Sopenharmony_ci case Expression::Kind::kConstructorMatrixResize: 311cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kConstructorMatrixResize_Command); 312cb93a386Sopenharmony_ci this->write(e->type()); 313cb93a386Sopenharmony_ci this->writeExpressionSpan(e->as<ConstructorMatrixResize>().argumentSpan()); 314cb93a386Sopenharmony_ci break; 315cb93a386Sopenharmony_ci 316cb93a386Sopenharmony_ci case Expression::Kind::kConstructorScalarCast: 317cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kConstructorScalarCast_Command); 318cb93a386Sopenharmony_ci this->write(e->type()); 319cb93a386Sopenharmony_ci this->writeExpressionSpan(e->as<ConstructorScalarCast>().argumentSpan()); 320cb93a386Sopenharmony_ci break; 321cb93a386Sopenharmony_ci 322cb93a386Sopenharmony_ci case Expression::Kind::kConstructorSplat: 323cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kConstructorSplat_Command); 324cb93a386Sopenharmony_ci this->write(e->type()); 325cb93a386Sopenharmony_ci this->writeExpressionSpan(e->as<ConstructorSplat>().argumentSpan()); 326cb93a386Sopenharmony_ci break; 327cb93a386Sopenharmony_ci 328cb93a386Sopenharmony_ci case Expression::Kind::kConstructorStruct: 329cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kConstructorStruct_Command); 330cb93a386Sopenharmony_ci this->write(e->type()); 331cb93a386Sopenharmony_ci this->writeExpressionSpan(e->as<ConstructorStruct>().argumentSpan()); 332cb93a386Sopenharmony_ci break; 333cb93a386Sopenharmony_ci 334cb93a386Sopenharmony_ci case Expression::Kind::kExternalFunctionCall: 335cb93a386Sopenharmony_ci case Expression::Kind::kExternalFunctionReference: 336cb93a386Sopenharmony_ci SkDEBUGFAIL("unimplemented--not expected to be used from within an include file"); 337cb93a386Sopenharmony_ci break; 338cb93a386Sopenharmony_ci 339cb93a386Sopenharmony_ci case Expression::Kind::kFieldAccess: { 340cb93a386Sopenharmony_ci const FieldAccess& f = e->as<FieldAccess>(); 341cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kFieldAccess_Command); 342cb93a386Sopenharmony_ci this->write(f.base().get()); 343cb93a386Sopenharmony_ci this->writeU8(f.fieldIndex()); 344cb93a386Sopenharmony_ci this->writeU8((int8_t) f.ownerKind()); 345cb93a386Sopenharmony_ci break; 346cb93a386Sopenharmony_ci } 347cb93a386Sopenharmony_ci case Expression::Kind::kFunctionCall: { 348cb93a386Sopenharmony_ci const FunctionCall& f = e->as<FunctionCall>(); 349cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kFunctionCall_Command); 350cb93a386Sopenharmony_ci this->write(f.type()); 351cb93a386Sopenharmony_ci this->writeId(&f.function()); 352cb93a386Sopenharmony_ci this->writeU8(f.arguments().size()); 353cb93a386Sopenharmony_ci for (const auto& a : f.arguments()) { 354cb93a386Sopenharmony_ci this->write(a.get()); 355cb93a386Sopenharmony_ci } 356cb93a386Sopenharmony_ci break; 357cb93a386Sopenharmony_ci } 358cb93a386Sopenharmony_ci case Expression::Kind::kIndex: { 359cb93a386Sopenharmony_ci const IndexExpression& i = e->as<IndexExpression>(); 360cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kIndex_Command); 361cb93a386Sopenharmony_ci this->write(i.base().get()); 362cb93a386Sopenharmony_ci this->write(i.index().get()); 363cb93a386Sopenharmony_ci break; 364cb93a386Sopenharmony_ci } 365cb93a386Sopenharmony_ci case Expression::Kind::kLiteral: { 366cb93a386Sopenharmony_ci const Literal& l = e->as<Literal>(); 367cb93a386Sopenharmony_ci if (l.type().isFloat()) { 368cb93a386Sopenharmony_ci float value = l.floatValue(); 369cb93a386Sopenharmony_ci int32_t floatBits; 370cb93a386Sopenharmony_ci memcpy(&floatBits, &value, sizeof(floatBits)); 371cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kFloatLiteral_Command); 372cb93a386Sopenharmony_ci this->write(l.type()); 373cb93a386Sopenharmony_ci this->writeS32(floatBits); 374cb93a386Sopenharmony_ci } else if (l.type().isBoolean()) { 375cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kBoolLiteral_Command); 376cb93a386Sopenharmony_ci this->writeU8(l.boolValue()); 377cb93a386Sopenharmony_ci } else { 378cb93a386Sopenharmony_ci SkASSERT(l.type().isInteger()); 379cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kIntLiteral_Command); 380cb93a386Sopenharmony_ci this->write(l.type()); 381cb93a386Sopenharmony_ci this->writeS32(l.intValue()); 382cb93a386Sopenharmony_ci } 383cb93a386Sopenharmony_ci break; 384cb93a386Sopenharmony_ci } 385cb93a386Sopenharmony_ci case Expression::Kind::kPostfix: { 386cb93a386Sopenharmony_ci const PostfixExpression& p = e->as<PostfixExpression>(); 387cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kPostfix_Command); 388cb93a386Sopenharmony_ci this->writeU8((int) p.getOperator().kind()); 389cb93a386Sopenharmony_ci this->write(p.operand().get()); 390cb93a386Sopenharmony_ci break; 391cb93a386Sopenharmony_ci } 392cb93a386Sopenharmony_ci case Expression::Kind::kPrefix: { 393cb93a386Sopenharmony_ci const PrefixExpression& p = e->as<PrefixExpression>(); 394cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kPrefix_Command); 395cb93a386Sopenharmony_ci this->writeU8((int) p.getOperator().kind()); 396cb93a386Sopenharmony_ci this->write(p.operand().get()); 397cb93a386Sopenharmony_ci break; 398cb93a386Sopenharmony_ci } 399cb93a386Sopenharmony_ci case Expression::Kind::kSetting: { 400cb93a386Sopenharmony_ci const Setting& s = e->as<Setting>(); 401cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kSetting_Command); 402cb93a386Sopenharmony_ci this->write(s.name()); 403cb93a386Sopenharmony_ci break; 404cb93a386Sopenharmony_ci } 405cb93a386Sopenharmony_ci case Expression::Kind::kSwizzle: { 406cb93a386Sopenharmony_ci const Swizzle& s = e->as<Swizzle>(); 407cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kSwizzle_Command); 408cb93a386Sopenharmony_ci this->write(s.base().get()); 409cb93a386Sopenharmony_ci this->writeU8(s.components().size()); 410cb93a386Sopenharmony_ci for (int c : s.components()) { 411cb93a386Sopenharmony_ci this->writeU8(c); 412cb93a386Sopenharmony_ci } 413cb93a386Sopenharmony_ci break; 414cb93a386Sopenharmony_ci } 415cb93a386Sopenharmony_ci case Expression::Kind::kTernary: { 416cb93a386Sopenharmony_ci const TernaryExpression& t = e->as<TernaryExpression>(); 417cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kTernary_Command); 418cb93a386Sopenharmony_ci this->write(t.test().get()); 419cb93a386Sopenharmony_ci this->write(t.ifTrue().get()); 420cb93a386Sopenharmony_ci this->write(t.ifFalse().get()); 421cb93a386Sopenharmony_ci break; 422cb93a386Sopenharmony_ci } 423cb93a386Sopenharmony_ci case Expression::Kind::kVariableReference: { 424cb93a386Sopenharmony_ci const VariableReference& v = e->as<VariableReference>(); 425cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kVariableReference_Command); 426cb93a386Sopenharmony_ci this->writeId(v.variable()); 427cb93a386Sopenharmony_ci this->writeU8((int8_t) v.refKind()); 428cb93a386Sopenharmony_ci break; 429cb93a386Sopenharmony_ci } 430cb93a386Sopenharmony_ci case Expression::Kind::kFunctionReference: 431cb93a386Sopenharmony_ci case Expression::Kind::kMethodReference: 432cb93a386Sopenharmony_ci case Expression::Kind::kPoison: 433cb93a386Sopenharmony_ci case Expression::Kind::kTypeReference: 434cb93a386Sopenharmony_ci SkDEBUGFAIL("this expression shouldn't appear in finished code"); 435cb93a386Sopenharmony_ci break; 436cb93a386Sopenharmony_ci } 437cb93a386Sopenharmony_ci } else { 438cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kVoid_Command); 439cb93a386Sopenharmony_ci } 440cb93a386Sopenharmony_ci} 441cb93a386Sopenharmony_ci 442cb93a386Sopenharmony_civoid Dehydrator::write(const Statement* s) { 443cb93a386Sopenharmony_ci if (s) { 444cb93a386Sopenharmony_ci switch (s->kind()) { 445cb93a386Sopenharmony_ci case Statement::Kind::kBlock: { 446cb93a386Sopenharmony_ci const Block& b = s->as<Block>(); 447cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kBlock_Command); 448cb93a386Sopenharmony_ci AutoDehydratorSymbolTable symbols(this, b.symbolTable()); 449cb93a386Sopenharmony_ci this->writeU8(b.children().size()); 450cb93a386Sopenharmony_ci for (const std::unique_ptr<Statement>& blockStmt : b.children()) { 451cb93a386Sopenharmony_ci this->write(blockStmt.get()); 452cb93a386Sopenharmony_ci } 453cb93a386Sopenharmony_ci this->writeU8(b.isScope()); 454cb93a386Sopenharmony_ci break; 455cb93a386Sopenharmony_ci } 456cb93a386Sopenharmony_ci case Statement::Kind::kBreak: 457cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kBreak_Command); 458cb93a386Sopenharmony_ci break; 459cb93a386Sopenharmony_ci case Statement::Kind::kContinue: 460cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kContinue_Command); 461cb93a386Sopenharmony_ci break; 462cb93a386Sopenharmony_ci case Statement::Kind::kDiscard: 463cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kDiscard_Command); 464cb93a386Sopenharmony_ci break; 465cb93a386Sopenharmony_ci case Statement::Kind::kDo: { 466cb93a386Sopenharmony_ci const DoStatement& d = s->as<DoStatement>(); 467cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kDo_Command); 468cb93a386Sopenharmony_ci this->write(d.statement().get()); 469cb93a386Sopenharmony_ci this->write(d.test().get()); 470cb93a386Sopenharmony_ci break; 471cb93a386Sopenharmony_ci } 472cb93a386Sopenharmony_ci case Statement::Kind::kExpression: { 473cb93a386Sopenharmony_ci const ExpressionStatement& e = s->as<ExpressionStatement>(); 474cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kExpressionStatement_Command); 475cb93a386Sopenharmony_ci this->write(e.expression().get()); 476cb93a386Sopenharmony_ci break; 477cb93a386Sopenharmony_ci } 478cb93a386Sopenharmony_ci case Statement::Kind::kFor: { 479cb93a386Sopenharmony_ci const ForStatement& f = s->as<ForStatement>(); 480cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kFor_Command); 481cb93a386Sopenharmony_ci this->write(f.initializer().get()); 482cb93a386Sopenharmony_ci this->write(f.test().get()); 483cb93a386Sopenharmony_ci this->write(f.next().get()); 484cb93a386Sopenharmony_ci this->write(f.statement().get()); 485cb93a386Sopenharmony_ci this->write(*f.symbols()); 486cb93a386Sopenharmony_ci break; 487cb93a386Sopenharmony_ci } 488cb93a386Sopenharmony_ci case Statement::Kind::kIf: { 489cb93a386Sopenharmony_ci const IfStatement& i = s->as<IfStatement>(); 490cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kIf_Command); 491cb93a386Sopenharmony_ci this->writeU8(i.isStatic()); 492cb93a386Sopenharmony_ci this->write(i.test().get()); 493cb93a386Sopenharmony_ci this->write(i.ifTrue().get()); 494cb93a386Sopenharmony_ci this->write(i.ifFalse().get()); 495cb93a386Sopenharmony_ci break; 496cb93a386Sopenharmony_ci } 497cb93a386Sopenharmony_ci case Statement::Kind::kInlineMarker: { 498cb93a386Sopenharmony_ci const InlineMarker& i = s->as<InlineMarker>(); 499cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kInlineMarker_Command); 500cb93a386Sopenharmony_ci this->writeId(&i.function()); 501cb93a386Sopenharmony_ci break; 502cb93a386Sopenharmony_ci } 503cb93a386Sopenharmony_ci case Statement::Kind::kNop: 504cb93a386Sopenharmony_ci SkDEBUGFAIL("unexpected--nop statement in finished code"); 505cb93a386Sopenharmony_ci break; 506cb93a386Sopenharmony_ci case Statement::Kind::kReturn: { 507cb93a386Sopenharmony_ci const ReturnStatement& r = s->as<ReturnStatement>(); 508cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kReturn_Command); 509cb93a386Sopenharmony_ci this->write(r.expression().get()); 510cb93a386Sopenharmony_ci break; 511cb93a386Sopenharmony_ci } 512cb93a386Sopenharmony_ci case Statement::Kind::kSwitch: { 513cb93a386Sopenharmony_ci const SwitchStatement& ss = s->as<SwitchStatement>(); 514cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kSwitch_Command); 515cb93a386Sopenharmony_ci this->writeU8(ss.isStatic()); 516cb93a386Sopenharmony_ci AutoDehydratorSymbolTable symbols(this, ss.symbols()); 517cb93a386Sopenharmony_ci this->write(ss.value().get()); 518cb93a386Sopenharmony_ci this->writeU8(ss.cases().size()); 519cb93a386Sopenharmony_ci for (const std::unique_ptr<Statement>& stmt : ss.cases()) { 520cb93a386Sopenharmony_ci const SwitchCase& sc = stmt->as<SwitchCase>(); 521cb93a386Sopenharmony_ci this->write(sc.value().get()); 522cb93a386Sopenharmony_ci this->write(sc.statement().get()); 523cb93a386Sopenharmony_ci } 524cb93a386Sopenharmony_ci break; 525cb93a386Sopenharmony_ci } 526cb93a386Sopenharmony_ci case Statement::Kind::kSwitchCase: 527cb93a386Sopenharmony_ci SkDEBUGFAIL("SwitchCase statements shouldn't appear here"); 528cb93a386Sopenharmony_ci break; 529cb93a386Sopenharmony_ci case Statement::Kind::kVarDeclaration: { 530cb93a386Sopenharmony_ci const VarDeclaration& v = s->as<VarDeclaration>(); 531cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kVarDeclaration_Command); 532cb93a386Sopenharmony_ci this->writeU16(this->symbolId(&v.var())); 533cb93a386Sopenharmony_ci this->write(v.baseType()); 534cb93a386Sopenharmony_ci this->writeS8(v.arraySize()); 535cb93a386Sopenharmony_ci this->write(v.value().get()); 536cb93a386Sopenharmony_ci break; 537cb93a386Sopenharmony_ci } 538cb93a386Sopenharmony_ci } 539cb93a386Sopenharmony_ci } else { 540cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kVoid_Command); 541cb93a386Sopenharmony_ci } 542cb93a386Sopenharmony_ci} 543cb93a386Sopenharmony_ci 544cb93a386Sopenharmony_civoid Dehydrator::write(const ProgramElement& e) { 545cb93a386Sopenharmony_ci switch (e.kind()) { 546cb93a386Sopenharmony_ci case ProgramElement::Kind::kExtension: 547cb93a386Sopenharmony_ci SkASSERT(false); 548cb93a386Sopenharmony_ci break; 549cb93a386Sopenharmony_ci case ProgramElement::Kind::kFunction: { 550cb93a386Sopenharmony_ci const FunctionDefinition& f = e.as<FunctionDefinition>(); 551cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kFunctionDefinition_Command); 552cb93a386Sopenharmony_ci this->writeU16(this->symbolId(&f.declaration())); 553cb93a386Sopenharmony_ci this->write(f.body().get()); 554cb93a386Sopenharmony_ci break; 555cb93a386Sopenharmony_ci } 556cb93a386Sopenharmony_ci case ProgramElement::Kind::kFunctionPrototype: { 557cb93a386Sopenharmony_ci // We don't need to emit function prototypes into the dehydrated data, because we don't 558cb93a386Sopenharmony_ci // ever need to re-emit the intrinsics files as raw GLSL/Metal. As long as the symbols 559cb93a386Sopenharmony_ci // exist in the symbol table, we're in good shape. 560cb93a386Sopenharmony_ci break; 561cb93a386Sopenharmony_ci } 562cb93a386Sopenharmony_ci case ProgramElement::Kind::kInterfaceBlock: { 563cb93a386Sopenharmony_ci const InterfaceBlock& i = e.as<InterfaceBlock>(); 564cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kInterfaceBlock_Command); 565cb93a386Sopenharmony_ci this->write(i.variable()); 566cb93a386Sopenharmony_ci this->write(i.typeName()); 567cb93a386Sopenharmony_ci this->write(i.instanceName()); 568cb93a386Sopenharmony_ci this->writeS8(i.arraySize()); 569cb93a386Sopenharmony_ci break; 570cb93a386Sopenharmony_ci } 571cb93a386Sopenharmony_ci case ProgramElement::Kind::kModifiers: 572cb93a386Sopenharmony_ci SkASSERT(false); 573cb93a386Sopenharmony_ci break; 574cb93a386Sopenharmony_ci case ProgramElement::Kind::kStructDefinition: { 575cb93a386Sopenharmony_ci const StructDefinition& structDef = e.as<StructDefinition>(); 576cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kStructDefinition_Command); 577cb93a386Sopenharmony_ci this->write(structDef.type()); 578cb93a386Sopenharmony_ci break; 579cb93a386Sopenharmony_ci } 580cb93a386Sopenharmony_ci case ProgramElement::Kind::kGlobalVar: { 581cb93a386Sopenharmony_ci const GlobalVarDeclaration& v = e.as<GlobalVarDeclaration>(); 582cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kVarDeclarations_Command); 583cb93a386Sopenharmony_ci this->write(v.declaration().get()); 584cb93a386Sopenharmony_ci break; 585cb93a386Sopenharmony_ci } 586cb93a386Sopenharmony_ci } 587cb93a386Sopenharmony_ci} 588cb93a386Sopenharmony_ci 589cb93a386Sopenharmony_civoid Dehydrator::write(const std::vector<std::unique_ptr<ProgramElement>>& elements) { 590cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kElements_Command); 591cb93a386Sopenharmony_ci for (const auto& e : elements) { 592cb93a386Sopenharmony_ci this->write(*e); 593cb93a386Sopenharmony_ci } 594cb93a386Sopenharmony_ci this->writeCommand(Rehydrator::kElementsComplete_Command); 595cb93a386Sopenharmony_ci} 596cb93a386Sopenharmony_ci 597cb93a386Sopenharmony_civoid Dehydrator::finish(OutputStream& out) { 598cb93a386Sopenharmony_ci String stringBuffer = fStringBuffer.str(); 599cb93a386Sopenharmony_ci String commandBuffer = fBody.str(); 600cb93a386Sopenharmony_ci 601cb93a386Sopenharmony_ci out.write16(fStringBuffer.str().size()); 602cb93a386Sopenharmony_ci fStringBufferStart = 2; 603cb93a386Sopenharmony_ci out.writeString(stringBuffer); 604cb93a386Sopenharmony_ci fCommandStart = fStringBufferStart + stringBuffer.size(); 605cb93a386Sopenharmony_ci out.writeString(commandBuffer); 606cb93a386Sopenharmony_ci} 607cb93a386Sopenharmony_ci 608cb93a386Sopenharmony_ciconst char* Dehydrator::prefixAtOffset(size_t byte) { 609cb93a386Sopenharmony_ci if (byte >= fCommandStart) { 610cb93a386Sopenharmony_ci return fCommandBreaks.contains(byte - fCommandStart) ? "\n" : ""; 611cb93a386Sopenharmony_ci } 612cb93a386Sopenharmony_ci if (byte >= fStringBufferStart) { 613cb93a386Sopenharmony_ci return fStringBreaks.contains(byte - fStringBufferStart) ? "\n" : ""; 614cb93a386Sopenharmony_ci } 615cb93a386Sopenharmony_ci return ""; 616cb93a386Sopenharmony_ci} 617cb93a386Sopenharmony_ci 618cb93a386Sopenharmony_ci} // namespace 619cb93a386Sopenharmony_ci 620cb93a386Sopenharmony_ci#endif 621