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