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