1 /* 2 * Copyright 2020 Google LLC. 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_REHYDRATOR 9 #define SKSL_REHYDRATOR 10 11 #include "include/private/SkSLDefines.h" 12 #include "include/private/SkSLModifiers.h" 13 #include "include/private/SkSLSymbol.h" 14 #include "src/sksl/SkSLContext.h" 15 16 #include <vector> 17 18 namespace SkSL { 19 20 class Context; 21 class ErrorReporter; 22 class Expression; 23 class IRGenerator; 24 class ProgramElement; 25 class Statement; 26 class SymbolTable; 27 class Type; 28 29 union FloatIntUnion { 30 float fFloat; 31 int32_t fInt; 32 }; 33 34 /** 35 * Interprets a simple bytecode format that encodes the structure of an SkSL IR tree. This is used 36 * to process the .sksl files representing SkSL's core include files, so that they can be quickly 37 * reconstituted at runtime. 38 */ 39 class Rehydrator { 40 public: 41 enum Command { 42 // uint16 id, Type componentType, uint8 count 43 kArrayType_Command, 44 // Expression left, uint8 op, Expression right, Type type 45 kBinary_Command, 46 // SymbolTable symbolTable, uint8 statementCount, Statement[] statements, bool isScope 47 kBlock_Command, 48 // bool value 49 kBoolLiteral_Command, 50 kBreak_Command, 51 // int16 builtin 52 kBuiltinLayout_Command, 53 // (All constructors) Type type, uint8 argCount, Expression[] arguments 54 kConstructorArray_Command, 55 kConstructorCompound_Command, 56 kConstructorCompoundCast_Command, 57 kConstructorDiagonalMatrix_Command, 58 kConstructorMatrixResize_Command, 59 kConstructorScalarCast_Command, 60 kConstructorSplat_Command, 61 kConstructorStruct_Command, 62 kContinue_Command, 63 kDefaultLayout_Command, 64 kDefaultModifiers_Command, 65 kDiscard_Command, 66 // Statement stmt, Expression test 67 kDo_Command, 68 // ProgramElement[] elements (reads until command `kElementsComplete_Command` is found) 69 kElements_Command, 70 // no arguments--indicates end of Elements list 71 kElementsComplete_Command, 72 // String typeName, SymbolTable symbols, int32[] values 73 kEnum_Command, 74 // uint16 id, String name 75 kEnumType_Command, 76 // Expression expression 77 kExpressionStatement_Command, 78 // uint16 ownerId, uint8 index 79 kField_Command, 80 // Expression base, uint8 index, uint8 ownerKind 81 kFieldAccess_Command, 82 // float value 83 kFloatLiteral_Command, 84 // Statement initializer, Expression test, Expression next, Statement body, 85 // SymbolTable symbols 86 kFor_Command, 87 // Type type, uint16 function, uint8 argCount, Expression[] arguments 88 kFunctionCall_Command, 89 // uint16 declaration, Statement body, uint8 refCount, uint16[] referencedIntrinsics 90 kFunctionDefinition_Command, 91 // uint16 id, Modifiers modifiers, String name, uint8 parameterCount, uint16[] parameterIds, 92 // Type returnType 93 kFunctionDeclaration_Command, 94 // bool isStatic, Expression test, Statement ifTrue, Statement ifFalse 95 kIf_Command, 96 // Expression base, Expression index 97 kIndex_Command, 98 // FunctionDeclaration function 99 kInlineMarker_Command, 100 // Variable* var, String typeName, String instanceName, uint8 sizeCount, Expression[] sizes 101 kInterfaceBlock_Command, 102 // int32 value 103 kIntLiteral_Command, 104 // int32 flags, int8 location, int8 offset, int8 binding, int8 index, int8 set, 105 // int16 builtin, int8 inputAttachmentIndex, int8 format, int8 primitive, int8 maxVertices, 106 // int8 invocations, String marker, String when, int8 key, int8 ctype 107 kLayout_Command, 108 // Layout layout, uint8 flags 109 kModifiers8Bit_Command, 110 // Layout layout, uint32 flags 111 kModifiers_Command, 112 // uint8 op, Expression operand 113 kPostfix_Command, 114 // uint8 op, Expression operand 115 kPrefix_Command, 116 // Expression value 117 kReturn_Command, 118 // String name, Expression value 119 kSetting_Command, 120 // uint16 id, Type structType 121 kStructDefinition_Command, 122 // uint16 id, String name, uint8 fieldCount, (Modifiers, String, Type)[] fields 123 kStructType_Command, 124 // bool isStatic, SymbolTable symbols, Expression value, uint8 caseCount, 125 // (Expression value, uint8 statementCount, Statement[] statements)[] cases 126 kSwitch_Command, 127 // Expression base, uint8 componentCount, uint8[] components 128 kSwizzle_Command, 129 // uint16 id 130 kSymbolRef_Command, 131 // String name, uint16 origSymbolId 132 kSymbolAlias_Command, 133 // uint16 owned symbol count, Symbol[] ownedSymbols, uint16 symbol count, 134 // (String, uint16/*index*/)[]. 135 kSymbolTable_Command, 136 // uint16 id, String name 137 kSystemType_Command, 138 // Expression test, Expression ifTrue, Expression ifFalse 139 kTernary_Command, 140 // uint16 id, FunctionDeclaration[] functions 141 kUnresolvedFunction_Command, 142 // uint16 id, Modifiers modifiers, String name, Type type, uint8 storage 143 kVariable_Command, 144 // uint16 varId, uint8 sizeCount, Expression[] sizes, Expression? value 145 kVarDeclaration_Command, 146 // Type baseType, uint8 varCount, VarDeclaration vars 147 kVarDeclarations_Command, 148 // uint16 varId, uint8 refKind 149 kVariableReference_Command, 150 kVoid_Command, 151 }; 152 153 // src must remain in memory as long as the objects created from it do 154 Rehydrator(const Context* context, std::shared_ptr<SymbolTable> symbolTable, 155 const uint8_t* src, size_t length); 156 157 std::vector<std::unique_ptr<ProgramElement>> elements(); 158 159 std::shared_ptr<SymbolTable> symbolTable(bool inherit = true); 160 161 private: readS8()162 int8_t readS8() { 163 SkASSERT(fIP < fEnd); 164 return *(fIP++); 165 } 166 readU8()167 uint8_t readU8() { 168 return this->readS8(); 169 } 170 readS16()171 int16_t readS16() { 172 uint8_t b1 = this->readU8(); 173 uint8_t b2 = this->readU8(); 174 return (b2 << 8) + b1; 175 } 176 readU16()177 uint16_t readU16() { 178 return this->readS16(); 179 } 180 readS32()181 int32_t readS32() { 182 uint8_t b1 = this->readU8(); 183 uint8_t b2 = this->readU8(); 184 uint8_t b3 = this->readU8(); 185 uint8_t b4 = this->readU8(); 186 return (b4 << 24) + (b3 << 16) + (b2 << 8) + b1; 187 } 188 readU32()189 uint32_t readU32() { 190 return this->readS32(); 191 } 192 readString()193 StringFragment readString() { 194 uint16_t offset = this->readU16(); 195 uint8_t length = *(uint8_t*) (fStart + offset); 196 const char* chars = (const char*) fStart + offset + 1; 197 return StringFragment(chars, length); 198 } 199 addSymbol(int id,const Symbol * symbol)200 void addSymbol(int id, const Symbol* symbol) { 201 while ((size_t) id >= fSymbols.size()) { 202 fSymbols.push_back(nullptr); 203 } 204 fSymbols[id] = symbol; 205 } 206 207 template<typename T> symbolRef(Symbol::Kind kind)208 T* symbolRef(Symbol::Kind kind) { 209 uint16_t result = this->readU16(); 210 SkASSERT(fSymbols.size() > result); 211 return (T*) fSymbols[result]; 212 } 213 214 Layout layout(); 215 216 Modifiers modifiers(); 217 218 const Symbol* symbol(); 219 220 std::unique_ptr<ProgramElement> element(); 221 222 std::unique_ptr<Statement> statement(); 223 224 std::unique_ptr<Expression> expression(); 225 226 ExpressionArray expressionArray(); 227 228 const Type* type(); 229 errorReporter()230 ErrorReporter* errorReporter() { return &fContext.fErrors; } 231 modifiersPool()232 ModifiersPool& modifiersPool() const { return *fContext.fModifiersPool; } 233 234 const Context& fContext; 235 std::shared_ptr<SymbolTable> fSymbolTable; 236 std::vector<const Symbol*> fSymbols; 237 238 const uint8_t* fStart; 239 const uint8_t* fIP; 240 SkDEBUGCODE(const uint8_t* fEnd;) 241 242 friend class AutoRehydratorSymbolTable; 243 }; 244 245 } // namespace SkSL 246 247 #endif 248