blob: 44fba3975c3415560f0d29ce249bc4d9fc209b01 [file] [log] [blame]
Ethan Nicholasc18bb512020-07-28 14:46:53 -04001/*
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#include "src/sksl/SkSLRehydrator.h"
John Stilesfbd050b2020-08-03 13:21:46 -04009
10#include <memory>
John Stilesb8e010c2020-08-11 18:05:39 -040011#include <unordered_set>
12
Ethan Nicholasdaed2592021-03-04 14:30:25 -050013#include "include/private/SkSLModifiers.h"
Ethan Nicholas24c17722021-03-09 13:10:59 -050014#include "include/private/SkSLProgramElement.h"
15#include "include/private/SkSLStatement.h"
Ethan Nicholasc18bb512020-07-28 14:46:53 -040016#include "src/sksl/ir/SkSLBinaryExpression.h"
17#include "src/sksl/ir/SkSLBreakStatement.h"
John Stilese1182782021-03-30 22:09:37 -040018#include "src/sksl/ir/SkSLConstructor.h"
John Stiles4118f142021-04-01 16:42:35 -040019#include "src/sksl/ir/SkSLConstructorArray.h"
John Stiles8cad6372021-04-07 12:31:13 -040020#include "src/sksl/ir/SkSLConstructorCompound.h"
21#include "src/sksl/ir/SkSLConstructorCompoundCast.h"
John Stilese1182782021-03-30 22:09:37 -040022#include "src/sksl/ir/SkSLConstructorDiagonalMatrix.h"
John Stiles5abb9e12021-04-06 13:47:19 -040023#include "src/sksl/ir/SkSLConstructorMatrixResize.h"
John Stilesfd7252f2021-04-04 22:24:40 -040024#include "src/sksl/ir/SkSLConstructorScalarCast.h"
John Stiles2938eea2021-04-01 18:58:25 -040025#include "src/sksl/ir/SkSLConstructorSplat.h"
John Stilesd47330f2021-04-08 23:25:52 -040026#include "src/sksl/ir/SkSLConstructorStruct.h"
Ethan Nicholasc18bb512020-07-28 14:46:53 -040027#include "src/sksl/ir/SkSLContinueStatement.h"
28#include "src/sksl/ir/SkSLDiscardStatement.h"
29#include "src/sksl/ir/SkSLDoStatement.h"
30#include "src/sksl/ir/SkSLEnum.h"
31#include "src/sksl/ir/SkSLExpression.h"
32#include "src/sksl/ir/SkSLExpressionStatement.h"
33#include "src/sksl/ir/SkSLField.h"
34#include "src/sksl/ir/SkSLFieldAccess.h"
35#include "src/sksl/ir/SkSLFloatLiteral.h"
36#include "src/sksl/ir/SkSLForStatement.h"
37#include "src/sksl/ir/SkSLFunctionCall.h"
38#include "src/sksl/ir/SkSLFunctionDeclaration.h"
39#include "src/sksl/ir/SkSLFunctionDefinition.h"
40#include "src/sksl/ir/SkSLIfStatement.h"
41#include "src/sksl/ir/SkSLIndexExpression.h"
John Stiles98c1f822020-09-09 14:18:53 -040042#include "src/sksl/ir/SkSLInlineMarker.h"
Ethan Nicholasc18bb512020-07-28 14:46:53 -040043#include "src/sksl/ir/SkSLIntLiteral.h"
44#include "src/sksl/ir/SkSLInterfaceBlock.h"
Ethan Nicholasc18bb512020-07-28 14:46:53 -040045#include "src/sksl/ir/SkSLPostfixExpression.h"
46#include "src/sksl/ir/SkSLPrefixExpression.h"
Ethan Nicholasc18bb512020-07-28 14:46:53 -040047#include "src/sksl/ir/SkSLReturnStatement.h"
48#include "src/sksl/ir/SkSLSetting.h"
John Stilesdc75a972020-11-25 16:24:55 -050049#include "src/sksl/ir/SkSLStructDefinition.h"
Ethan Nicholasc18bb512020-07-28 14:46:53 -040050#include "src/sksl/ir/SkSLSwitchCase.h"
51#include "src/sksl/ir/SkSLSwitchStatement.h"
52#include "src/sksl/ir/SkSLSwizzle.h"
John Stiles49a547f2020-10-06 16:14:37 -040053#include "src/sksl/ir/SkSLSymbolAlias.h"
Ethan Nicholasc18bb512020-07-28 14:46:53 -040054#include "src/sksl/ir/SkSLSymbolTable.h"
55#include "src/sksl/ir/SkSLTernaryExpression.h"
56#include "src/sksl/ir/SkSLType.h"
57#include "src/sksl/ir/SkSLUnresolvedFunction.h"
58#include "src/sksl/ir/SkSLVarDeclarations.h"
Ethan Nicholasc18bb512020-07-28 14:46:53 -040059#include "src/sksl/ir/SkSLVariable.h"
Ethan Nicholasc18bb512020-07-28 14:46:53 -040060
61namespace SkSL {
62
63class AutoRehydratorSymbolTable {
64public:
65 AutoRehydratorSymbolTable(Rehydrator* rehydrator)
66 : fRehydrator(rehydrator)
67 , fOldSymbols(fRehydrator->fSymbolTable) {
68 fRehydrator->fSymbolTable = fRehydrator->symbolTable();
69 }
70
71 ~AutoRehydratorSymbolTable() {
72 fRehydrator->fSymbolTable = std::move(fOldSymbols);
73 }
74
75private:
76 Rehydrator* fRehydrator;
77 std::shared_ptr<SymbolTable> fOldSymbols;
78};
79
John Stiles7c3515b2020-10-16 18:38:39 -040080Rehydrator::Rehydrator(const Context* context, ModifiersPool* modifiers,
John Stilesf2872e62021-05-04 11:38:43 -040081 std::shared_ptr<SymbolTable> symbolTable,
John Stiles7c3515b2020-10-16 18:38:39 -040082 const uint8_t* src, size_t length)
83 : fContext(*context)
84 , fModifiers(*modifiers)
John Stiles7c3515b2020-10-16 18:38:39 -040085 , fSymbolTable(std::move(symbolTable))
86 , fStart(src)
87 SkDEBUGCODE(, fEnd(fStart + length)) {
88 SkASSERT(fSymbolTable);
89 SkASSERT(fSymbolTable->isBuiltin());
90 // skip past string data
91 fIP = fStart;
92 fIP += this->readU16();
93}
94
Ethan Nicholasc18bb512020-07-28 14:46:53 -040095Layout Rehydrator::layout() {
96 switch (this->readU8()) {
97 case kBuiltinLayout_Command: {
98 Layout result;
99 result.fBuiltin = this->readS16();
100 return result;
101 }
102 case kDefaultLayout_Command:
103 return Layout();
104 case kLayout_Command: {
105 int flags = this->readU32();
106 int location = this->readS8();
107 int offset = this->readS8();
108 int binding = this->readS8();
109 int index = this->readS8();
110 int set = this->readS8();
111 int builtin = this->readS16();
112 int inputAttachmentIndex = this->readS8();
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400113 int primitive = this->readS8();
114 int maxVertices = this->readS8();
115 int invocations = this->readS8();
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400116 StringFragment when = this->readString();
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400117 int ctype = this->readS8();
118 return Layout(flags, location, offset, binding, index, set, builtin,
Brian Osman4717fbb2021-02-23 13:12:09 -0500119 inputAttachmentIndex, (Layout::Primitive)primitive, maxVertices,
Brian Osman8f1dff62021-04-19 13:50:58 -0400120 invocations, when, (Layout::CType)ctype);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400121 }
122 default:
123 SkASSERT(false);
124 return Layout();
125 }
126}
127
128Modifiers Rehydrator::modifiers() {
129 switch (this->readU8()) {
130 case kDefaultModifiers_Command:
131 return Modifiers();
132 case kModifiers8Bit_Command: {
133 Layout l = this->layout();
134 int flags = this->readU8();
135 return Modifiers(l, flags);
136 }
137 case kModifiers_Command: {
138 Layout l = this->layout();
139 int flags = this->readS32();
140 return Modifiers(l, flags);
141 }
142 default:
143 SkASSERT(false);
144 return Modifiers();
145 }
146}
147
Brian Osman5bf3e202020-10-13 10:34:18 -0400148const Symbol* Rehydrator::symbol() {
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400149 int kind = this->readU8();
150 switch (kind) {
151 case kArrayType_Command: {
152 uint16_t id = this->readU16();
153 const Type* componentType = this->type();
Brian Osmane8c26082020-10-01 17:22:45 -0400154 int8_t count = this->readS8();
155 String name = componentType->name();
156 if (count == Type::kUnsizedArray) {
157 name += "[]";
158 } else {
159 name += "[" + to_string(count) + "]";
160 }
Brian Osman5bf3e202020-10-13 10:34:18 -0400161 const Type* result = fSymbolTable->takeOwnershipOfSymbol(
John Stilesad2d4942020-12-11 16:55:58 -0500162 Type::MakeArrayType(name, *componentType, count));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400163 this->addSymbol(id, result);
164 return result;
165 }
166 case kEnumType_Command: {
167 uint16_t id = this->readU16();
168 StringFragment name = this->readString();
John Stilese6c67c52021-01-15 12:01:00 -0500169 const Type* result = fSymbolTable->takeOwnershipOfSymbol(Type::MakeEnumType(name));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400170 this->addSymbol(id, result);
171 return result;
172 }
173 case kFunctionDeclaration_Command: {
174 uint16_t id = this->readU16();
175 Modifiers modifiers = this->modifiers();
176 StringFragment name = this->readString();
177 int parameterCount = this->readU8();
Brian Osman5bf3e202020-10-13 10:34:18 -0400178 std::vector<const Variable*> parameters;
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400179 parameters.reserve(parameterCount);
180 for (int i = 0; i < parameterCount; ++i) {
Ethan Nicholase6592142020-09-08 10:22:09 -0400181 parameters.push_back(this->symbolRef<Variable>(Symbol::Kind::kVariable));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400182 }
183 const Type* returnType = this->type();
Brian Osman5bf3e202020-10-13 10:34:18 -0400184 const FunctionDeclaration* result =
John Stiles3ae071e2020-08-05 15:29:29 -0400185 fSymbolTable->takeOwnershipOfSymbol(std::make_unique<FunctionDeclaration>(
John Stilesf2872e62021-05-04 11:38:43 -0400186 /*offset=*/-1,
187 this->modifiersPool().add(modifiers),
188 name,
189 std::move(parameters),
190 returnType,
191 /*builtin=*/true));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400192 this->addSymbol(id, result);
193 return result;
194 }
195 case kField_Command: {
Ethan Nicholase6592142020-09-08 10:22:09 -0400196 const Variable* owner = this->symbolRef<Variable>(Symbol::Kind::kVariable);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400197 uint8_t index = this->readU8();
Brian Osman5bf3e202020-10-13 10:34:18 -0400198 const Field* result = fSymbolTable->takeOwnershipOfSymbol(
Ethan Nicholase2c49992020-10-05 11:49:11 -0400199 std::make_unique<Field>(/*offset=*/-1, owner, index));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400200 return result;
201 }
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400202 case kStructType_Command: {
203 uint16_t id = this->readU16();
204 StringFragment name = this->readString();
205 uint8_t fieldCount = this->readU8();
206 std::vector<Type::Field> fields;
207 fields.reserve(fieldCount);
208 for (int i = 0; i < fieldCount; ++i) {
209 Modifiers m = this->modifiers();
John Stilesf621e232020-08-25 13:33:02 -0400210 StringFragment fieldName = this->readString();
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400211 const Type* type = this->type();
John Stilesf621e232020-08-25 13:33:02 -0400212 fields.emplace_back(m, fieldName, type);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400213 }
Brian Osman5bf3e202020-10-13 10:34:18 -0400214 const Type* result = fSymbolTable->takeOwnershipOfSymbol(
John Stilesad2d4942020-12-11 16:55:58 -0500215 Type::MakeStructType(/*offset=*/-1, name, std::move(fields)));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400216 this->addSymbol(id, result);
217 return result;
218 }
219 case kSymbolRef_Command: {
220 uint16_t id = this->readU16();
221 SkASSERT(fSymbols.size() > id);
222 return fSymbols[id];
223 }
John Stiles49a547f2020-10-06 16:14:37 -0400224 case kSymbolAlias_Command: {
225 uint16_t id = this->readU16();
226 StringFragment name = this->readString();
Brian Osman5bf3e202020-10-13 10:34:18 -0400227 const Symbol* origSymbol = this->symbol();
228 const SymbolAlias* symbolAlias = fSymbolTable->takeOwnershipOfSymbol(
John Stiles49a547f2020-10-06 16:14:37 -0400229 std::make_unique<SymbolAlias>(/*offset=*/-1, name, origSymbol));
230 this->addSymbol(id, symbolAlias);
231 return symbolAlias;
232 }
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400233 case kSystemType_Command: {
234 uint16_t id = this->readU16();
235 StringFragment name = this->readString();
Brian Osman5bf3e202020-10-13 10:34:18 -0400236 const Symbol* result = (*fSymbolTable)[name];
Ethan Nicholase6592142020-09-08 10:22:09 -0400237 SkASSERT(result && result->kind() == Symbol::Kind::kType);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400238 this->addSymbol(id, result);
239 return result;
240 }
241 case kUnresolvedFunction_Command: {
242 uint16_t id = this->readU16();
243 int length = this->readU8();
244 std::vector<const FunctionDeclaration*> functions;
245 functions.reserve(length);
246 for (int i = 0; i < length; ++i) {
247 const Symbol* f = this->symbol();
Ethan Nicholase6592142020-09-08 10:22:09 -0400248 SkASSERT(f && f->kind() == Symbol::Kind::kFunctionDeclaration);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400249 functions.push_back((const FunctionDeclaration*) f);
250 }
Brian Osman5bf3e202020-10-13 10:34:18 -0400251 const UnresolvedFunction* result = fSymbolTable->takeOwnershipOfSymbol(
John Stiles3ae071e2020-08-05 15:29:29 -0400252 std::make_unique<UnresolvedFunction>(std::move(functions)));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400253 this->addSymbol(id, result);
254 return result;
255 }
256 case kVariable_Command: {
257 uint16_t id = this->readU16();
John Stilesf2872e62021-05-04 11:38:43 -0400258 const Modifiers* m = this->modifiersPool().add(this->modifiers());
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400259 StringFragment name = this->readString();
260 const Type* type = this->type();
261 Variable::Storage storage = (Variable::Storage) this->readU8();
Brian Osman5bf3e202020-10-13 10:34:18 -0400262 const Variable* result = fSymbolTable->takeOwnershipOfSymbol(std::make_unique<Variable>(
Brian Osman3887a012020-09-30 13:22:27 -0400263 /*offset=*/-1, m, name, type, /*builtin=*/true, storage));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400264 this->addSymbol(id, result);
265 return result;
266 }
267 default:
268 printf("unsupported symbol %d\n", kind);
269 SkASSERT(false);
270 return nullptr;
271 }
272}
273
274const Type* Rehydrator::type() {
275 const Symbol* result = this->symbol();
Ethan Nicholase6592142020-09-08 10:22:09 -0400276 SkASSERT(result->kind() == Symbol::Kind::kType);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400277 return (const Type*) result;
278}
279
280std::vector<std::unique_ptr<ProgramElement>> Rehydrator::elements() {
281 SkDEBUGCODE(uint8_t command = )this->readU8();
282 SkASSERT(command == kElements_Command);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400283 std::vector<std::unique_ptr<ProgramElement>> result;
John Stiles1ea7f542020-11-02 13:07:23 -0500284 while (std::unique_ptr<ProgramElement> elem = this->element()) {
285 result.push_back(std::move(elem));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400286 }
287 return result;
288}
289
290std::unique_ptr<ProgramElement> Rehydrator::element() {
291 int kind = this->readU8();
292 switch (kind) {
293 case Rehydrator::kEnum_Command: {
294 StringFragment typeName = this->readString();
Brian Osman1313d1a2020-09-08 10:34:30 -0400295 std::shared_ptr<SymbolTable> symbols = this->symbolTable(/*inherit=*/false);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400296 for (auto& s : symbols->fOwnedSymbols) {
Ethan Nicholase6592142020-09-08 10:22:09 -0400297 SkASSERT(s->kind() == Symbol::Kind::kVariable);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400298 Variable& v = (Variable&) *s;
299 int value = this->readS32();
Ethan Nicholas5b9b0db2021-01-21 13:12:01 -0500300 // enum variables aren't really 'declared', but we have to create a declaration to
301 // store the value
John Stiles9ce80f72021-03-11 22:35:19 -0500302 auto valueLiteral = IntLiteral::Make(fContext, /*offset=*/-1, value);
John Stilese67bd132021-03-19 18:39:25 -0400303 auto declaration = VarDeclaration::Make(fContext, &v, &v.type(), /*arraySize=*/0,
304 std::move(valueLiteral));
Ethan Nicholas5b9b0db2021-01-21 13:12:01 -0500305 symbols->takeOwnershipOfIRNode(std::move(declaration));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400306 }
John Stiles1c823672020-10-20 10:23:50 -0400307 return std::make_unique<Enum>(/*offset=*/-1, typeName, std::move(symbols),
308 /*isSharedWithCpp=*/true, /*isBuiltin=*/true);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400309 }
310 case Rehydrator::kFunctionDefinition_Command: {
311 const FunctionDeclaration* decl = this->symbolRef<FunctionDeclaration>(
Ethan Nicholase6592142020-09-08 10:22:09 -0400312 Symbol::Kind::kFunctionDeclaration);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400313 std::unique_ptr<Statement> body = this->statement();
John Stilesb8e010c2020-08-11 18:05:39 -0400314 std::unordered_set<const FunctionDeclaration*> refs;
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400315 uint8_t refCount = this->readU8();
316 for (int i = 0; i < refCount; ++i) {
317 refs.insert(this->symbolRef<FunctionDeclaration>(
Ethan Nicholase6592142020-09-08 10:22:09 -0400318 Symbol::Kind::kFunctionDeclaration));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400319 }
John Stiles607d36b2020-10-19 15:00:01 -0400320 auto result = std::make_unique<FunctionDefinition>(/*offset=*/-1, decl,
321 /*builtin=*/true, std::move(body),
322 std::move(refs));
323 decl->setDefinition(result.get());
324 return std::move(result);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400325 }
326 case Rehydrator::kInterfaceBlock_Command: {
327 const Symbol* var = this->symbol();
John Stiles87ae34e2020-10-13 12:50:11 -0400328 SkASSERT(var && var->is<Variable>());
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400329 StringFragment typeName = this->readString();
330 StringFragment instanceName = this->readString();
John Stilesd39aec02020-12-03 10:42:26 -0500331 int arraySize = this->readS8();
John Stiles87ae34e2020-10-13 12:50:11 -0400332 return std::make_unique<InterfaceBlock>(/*offset=*/-1, &var->as<Variable>(), typeName,
John Stilesd39aec02020-12-03 10:42:26 -0500333 instanceName, arraySize, nullptr);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400334 }
335 case Rehydrator::kVarDeclarations_Command: {
Brian Osmanc0213602020-10-06 14:43:32 -0400336 std::unique_ptr<Statement> decl = this->statement();
Ethan Nicholas624a5292021-04-16 14:54:43 -0400337 return std::make_unique<GlobalVarDeclaration>(std::move(decl));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400338 }
John Stilesdc75a972020-11-25 16:24:55 -0500339 case Rehydrator::kStructDefinition_Command: {
340 const Symbol* type = this->symbol();
341 SkASSERT(type && type->is<Type>());
342 return std::make_unique<StructDefinition>(/*offset=*/-1, type->as<Type>());
343 }
John Stiles1ea7f542020-11-02 13:07:23 -0500344 case Rehydrator::kElementsComplete_Command:
345 return nullptr;
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400346 default:
John Stiles1ea7f542020-11-02 13:07:23 -0500347 SkDEBUGFAILF("unsupported element %d\n", kind);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400348 return nullptr;
349 }
350}
351
352std::unique_ptr<Statement> Rehydrator::statement() {
353 int kind = this->readU8();
354 switch (kind) {
355 case Rehydrator::kBlock_Command: {
356 AutoRehydratorSymbolTable symbols(this);
357 int count = this->readU8();
John Stiles8f2a0cf2020-10-13 12:48:21 -0400358 StatementArray statements;
John Stilesf4bda742020-10-14 16:57:41 -0400359 statements.reserve_back(count);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400360 for (int i = 0; i < count; ++i) {
361 statements.push_back(this->statement());
362 }
363 bool isScope = this->readU8();
John Stilesbf16b6c2021-03-12 19:24:31 -0500364 return Block::Make(/*offset=*/-1, std::move(statements), fSymbolTable, isScope);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400365 }
366 case Rehydrator::kBreak_Command:
John Stilesa0c04d62021-03-11 23:07:24 -0500367 return BreakStatement::Make(/*offset=*/-1);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400368 case Rehydrator::kContinue_Command:
John Stilesa0c04d62021-03-11 23:07:24 -0500369 return ContinueStatement::Make(/*offset=*/-1);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400370 case Rehydrator::kDiscard_Command:
John Stilesa0c04d62021-03-11 23:07:24 -0500371 return DiscardStatement::Make(/*offset=*/-1);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400372 case Rehydrator::kDo_Command: {
373 std::unique_ptr<Statement> stmt = this->statement();
374 std::unique_ptr<Expression> expr = this->expression();
John Stilesea5822e2021-02-26 11:18:20 -0500375 return DoStatement::Make(fContext, std::move(stmt), std::move(expr));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400376 }
377 case Rehydrator::kExpressionStatement_Command: {
378 std::unique_ptr<Expression> expr = this->expression();
John Stiles3e5871c2021-02-25 20:52:03 -0500379 return ExpressionStatement::Make(fContext, std::move(expr));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400380 }
381 case Rehydrator::kFor_Command: {
382 std::unique_ptr<Statement> initializer = this->statement();
383 std::unique_ptr<Expression> test = this->expression();
384 std::unique_ptr<Expression> next = this->expression();
385 std::unique_ptr<Statement> body = this->statement();
386 std::shared_ptr<SymbolTable> symbols = this->symbolTable();
John Stiles23521a82021-03-02 17:02:51 -0500387 return ForStatement::Make(fContext, /*offset=*/-1, std::move(initializer),
388 std::move(test), std::move(next), std::move(body),
389 std::move(symbols));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400390 }
391 case Rehydrator::kIf_Command: {
392 bool isStatic = this->readU8();
393 std::unique_ptr<Expression> test = this->expression();
394 std::unique_ptr<Statement> ifTrue = this->statement();
395 std::unique_ptr<Statement> ifFalse = this->statement();
John Stilescf3059e2021-02-25 14:27:02 -0500396 return IfStatement::Make(fContext, /*offset=*/-1, isStatic, std::move(test),
397 std::move(ifTrue), std::move(ifFalse));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400398 }
John Stiles98c1f822020-09-09 14:18:53 -0400399 case Rehydrator::kInlineMarker_Command: {
400 const FunctionDeclaration* funcDecl = this->symbolRef<FunctionDeclaration>(
401 Symbol::Kind::kFunctionDeclaration);
John Stilesa0c04d62021-03-11 23:07:24 -0500402 return InlineMarker::Make(funcDecl);
John Stiles98c1f822020-09-09 14:18:53 -0400403 }
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400404 case Rehydrator::kReturn_Command: {
405 std::unique_ptr<Expression> expr = this->expression();
John Stilesa0c04d62021-03-11 23:07:24 -0500406 return ReturnStatement::Make(/*offset=*/-1, std::move(expr));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400407 }
408 case Rehydrator::kSwitch_Command: {
409 bool isStatic = this->readU8();
410 AutoRehydratorSymbolTable symbols(this);
411 std::unique_ptr<Expression> expr = this->expression();
412 int caseCount = this->readU8();
John Stilesb23a64b2021-03-11 08:27:59 -0500413 StatementArray cases;
414 cases.reserve_back(caseCount);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400415 for (int i = 0; i < caseCount; ++i) {
416 std::unique_ptr<Expression> value = this->expression();
John Stilesc3ce43b2021-03-09 15:37:01 -0500417 std::unique_ptr<Statement> statement = this->statement();
John Stiles8f2a0cf2020-10-13 12:48:21 -0400418 cases.push_back(std::make_unique<SwitchCase>(/*offset=*/-1, std::move(value),
John Stilesc3ce43b2021-03-09 15:37:01 -0500419 std::move(statement)));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400420 }
John Stiles23521a82021-03-02 17:02:51 -0500421 return SwitchStatement::Make(fContext, /*offset=*/-1, isStatic, std::move(expr),
422 std::move(cases), fSymbolTable);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400423 }
424 case Rehydrator::kVarDeclaration_Command: {
Ethan Nicholase6592142020-09-08 10:22:09 -0400425 Variable* var = this->symbolRef<Variable>(Symbol::Kind::kVariable);
Brian Osmanc0213602020-10-06 14:43:32 -0400426 const Type* baseType = this->type();
John Stiles62a56462020-12-03 10:41:58 -0500427 int arraySize = this->readS8();
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400428 std::unique_ptr<Expression> value = this->expression();
John Stilese67bd132021-03-19 18:39:25 -0400429 return VarDeclaration::Make(fContext, var, baseType, arraySize, std::move(value));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400430 }
431 case Rehydrator::kVoid_Command:
432 return nullptr;
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400433 default:
434 printf("unsupported statement %d\n", kind);
435 SkASSERT(false);
436 return nullptr;
437 }
438}
439
John Stilesd8eb8752021-04-01 11:49:10 -0400440ExpressionArray Rehydrator::expressionArray() {
441 uint8_t count = this->readU8();
442 ExpressionArray array;
443 array.reserve_back(count);
444 for (int i = 0; i < count; ++i) {
445 array.push_back(this->expression());
446 }
447 return array;
448}
449
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400450std::unique_ptr<Expression> Rehydrator::expression() {
451 int kind = this->readU8();
452 switch (kind) {
453 case Rehydrator::kBinary_Command: {
454 std::unique_ptr<Expression> left = this->expression();
455 Token::Kind op = (Token::Kind) this->readU8();
456 std::unique_ptr<Expression> right = this->expression();
John Stilese2aec432021-03-01 09:27:48 -0500457 return BinaryExpression::Make(fContext, std::move(left), op, std::move(right));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400458 }
459 case Rehydrator::kBoolLiteral_Command: {
460 bool value = this->readU8();
John Stiles9ce80f72021-03-11 22:35:19 -0500461 return BoolLiteral::Make(fContext, /*offset=*/-1, value);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400462 }
John Stiles4118f142021-04-01 16:42:35 -0400463 case Rehydrator::kConstructorArray_Command: {
464 const Type* type = this->type();
465 return ConstructorArray::Make(fContext, /*offset=*/-1, *type, this->expressionArray());
466 }
John Stiles8cad6372021-04-07 12:31:13 -0400467 case Rehydrator::kConstructorCompound_Command: {
John Stiles2bec8ab2021-04-06 18:40:04 -0400468 const Type* type = this->type();
John Stiles8cad6372021-04-07 12:31:13 -0400469 return ConstructorCompound::Make(fContext, /*offset=*/-1, *type,
John Stiles2bec8ab2021-04-06 18:40:04 -0400470 this->expressionArray());
471 }
John Stilese1182782021-03-30 22:09:37 -0400472 case Rehydrator::kConstructorDiagonalMatrix_Command: {
473 const Type* type = this->type();
John Stilesd8eb8752021-04-01 11:49:10 -0400474 ExpressionArray args = this->expressionArray();
475 SkASSERT(args.size() == 1);
John Stilese1182782021-03-30 22:09:37 -0400476 return ConstructorDiagonalMatrix::Make(fContext, /*offset=*/-1, *type,
John Stilesd8eb8752021-04-01 11:49:10 -0400477 std::move(args[0]));
John Stilese1182782021-03-30 22:09:37 -0400478 }
John Stiles5abb9e12021-04-06 13:47:19 -0400479 case Rehydrator::kConstructorMatrixResize_Command: {
480 const Type* type = this->type();
481 ExpressionArray args = this->expressionArray();
482 SkASSERT(args.size() == 1);
483 return ConstructorMatrixResize::Make(fContext, /*offset=*/-1, *type,
484 std::move(args[0]));
485 }
John Stilesfd7252f2021-04-04 22:24:40 -0400486 case Rehydrator::kConstructorScalarCast_Command: {
487 const Type* type = this->type();
488 ExpressionArray args = this->expressionArray();
489 SkASSERT(args.size() == 1);
490 return ConstructorScalarCast::Make(fContext, /*offset=*/-1, *type, std::move(args[0]));
491 }
John Stiles2938eea2021-04-01 18:58:25 -0400492 case Rehydrator::kConstructorSplat_Command: {
493 const Type* type = this->type();
494 ExpressionArray args = this->expressionArray();
495 SkASSERT(args.size() == 1);
496 return ConstructorSplat::Make(fContext, /*offset=*/-1, *type, std::move(args[0]));
497 }
John Stilesd47330f2021-04-08 23:25:52 -0400498 case Rehydrator::kConstructorStruct_Command: {
499 const Type* type = this->type();
500 return ConstructorStruct::Make(fContext, /*offset=*/-1, *type, this->expressionArray());
501 }
John Stiles8cad6372021-04-07 12:31:13 -0400502 case Rehydrator::kConstructorCompoundCast_Command: {
John Stilesb14a8192021-04-05 11:40:46 -0400503 const Type* type = this->type();
504 ExpressionArray args = this->expressionArray();
505 SkASSERT(args.size() == 1);
John Stiles8cad6372021-04-07 12:31:13 -0400506 return ConstructorCompoundCast::Make(fContext,/*offset=*/-1, *type, std::move(args[0]));
John Stilesb14a8192021-04-05 11:40:46 -0400507 }
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400508 case Rehydrator::kFieldAccess_Command: {
509 std::unique_ptr<Expression> base = this->expression();
510 int index = this->readU8();
511 FieldAccess::OwnerKind ownerKind = (FieldAccess::OwnerKind) this->readU8();
John Stiles06d600f2021-03-08 09:18:21 -0500512 return FieldAccess::Make(fContext, std::move(base), index, ownerKind);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400513 }
514 case Rehydrator::kFloatLiteral_Command: {
Brian Osmanfb964a42020-11-18 10:45:52 -0500515 const Type* type = this->type();
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400516 FloatIntUnion u;
517 u.fInt = this->readS32();
John Stiles9ce80f72021-03-11 22:35:19 -0500518 return FloatLiteral::Make(/*offset=*/-1, u.fFloat, type);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400519 }
520 case Rehydrator::kFunctionCall_Command: {
Ethan Nicholas30d30222020-09-11 12:27:26 -0400521 const Type* type = this->type();
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400522 const FunctionDeclaration* f = this->symbolRef<FunctionDeclaration>(
Ethan Nicholase6592142020-09-08 10:22:09 -0400523 Symbol::Kind::kFunctionDeclaration);
John Stilesd8eb8752021-04-01 11:49:10 -0400524 ExpressionArray args = this->expressionArray();
John Stilescd7ba502021-03-19 10:54:59 -0400525 return FunctionCall::Make(fContext, /*offset=*/-1, type, *f, std::move(args));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400526 }
527 case Rehydrator::kIndex_Command: {
528 std::unique_ptr<Expression> base = this->expression();
529 std::unique_ptr<Expression> index = this->expression();
John Stiles51d33982021-03-08 09:18:07 -0500530 return IndexExpression::Make(fContext, std::move(base), std::move(index));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400531 }
532 case Rehydrator::kIntLiteral_Command: {
Brian Osmanfb964a42020-11-18 10:45:52 -0500533 const Type* type = this->type();
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400534 int value = this->readS32();
John Stiles9ce80f72021-03-11 22:35:19 -0500535 return IntLiteral::Make(/*offset=*/-1, value, type);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400536 }
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400537 case Rehydrator::kPostfix_Command: {
538 Token::Kind op = (Token::Kind) this->readU8();
539 std::unique_ptr<Expression> operand = this->expression();
John Stiles52d3b012021-02-26 15:56:48 -0500540 return PostfixExpression::Make(fContext, std::move(operand), op);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400541 }
542 case Rehydrator::kPrefix_Command: {
543 Token::Kind op = (Token::Kind) this->readU8();
544 std::unique_ptr<Expression> operand = this->expression();
John Stilesb0eb20f2021-02-26 15:29:33 -0500545 return PrefixExpression::Make(fContext, op, std::move(operand));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400546 }
547 case Rehydrator::kSetting_Command: {
548 StringFragment name = this->readString();
John Stiles23521a82021-03-02 17:02:51 -0500549 return Setting::Convert(fContext, /*offset=*/-1, name);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400550 }
551 case Rehydrator::kSwizzle_Command: {
552 std::unique_ptr<Expression> base = this->expression();
553 int count = this->readU8();
John Stiles750109b2020-10-30 13:45:46 -0400554 ComponentArray components;
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400555 for (int i = 0; i < count; ++i) {
556 components.push_back(this->readU8());
557 }
John Stiles23521a82021-03-02 17:02:51 -0500558 return Swizzle::Make(fContext, std::move(base), components);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400559 }
560 case Rehydrator::kTernary_Command: {
561 std::unique_ptr<Expression> test = this->expression();
562 std::unique_ptr<Expression> ifTrue = this->expression();
563 std::unique_ptr<Expression> ifFalse = this->expression();
John Stiles90518f72021-02-26 20:44:54 -0500564 return TernaryExpression::Make(fContext, std::move(test),
565 std::move(ifTrue), std::move(ifFalse));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400566 }
567 case Rehydrator::kVariableReference_Command: {
Ethan Nicholase6592142020-09-08 10:22:09 -0400568 const Variable* var = this->symbolRef<Variable>(Symbol::Kind::kVariable);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400569 VariableReference::RefKind refKind = (VariableReference::RefKind) this->readU8();
John Stilesa94e0262021-04-27 17:29:59 -0400570 return VariableReference::Make(/*offset=*/-1, var, refKind);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400571 }
572 case Rehydrator::kVoid_Command:
573 return nullptr;
574 default:
575 printf("unsupported expression %d\n", kind);
576 SkASSERT(false);
577 return nullptr;
578 }
579}
580
Brian Osman1313d1a2020-09-08 10:34:30 -0400581std::shared_ptr<SymbolTable> Rehydrator::symbolTable(bool inherit) {
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400582 int command = this->readU8();
583 if (command == kVoid_Command) {
584 return nullptr;
585 }
586 SkASSERT(command == kSymbolTable_Command);
587 uint16_t ownedCount = this->readU16();
Brian Osman1313d1a2020-09-08 10:34:30 -0400588 std::shared_ptr<SymbolTable> oldTable = fSymbolTable;
John Stiles7c3515b2020-10-16 18:38:39 -0400589 std::shared_ptr<SymbolTable> result =
590 inherit ? std::make_shared<SymbolTable>(fSymbolTable, /*builtin=*/true)
John Stilesf2872e62021-05-04 11:38:43 -0400591 : std::make_shared<SymbolTable>(this->errorReporter(), /*builtin=*/true);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400592 fSymbolTable = result;
Brian Osman5bf3e202020-10-13 10:34:18 -0400593 std::vector<const Symbol*> ownedSymbols;
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400594 ownedSymbols.reserve(ownedCount);
595 for (int i = 0; i < ownedCount; ++i) {
596 ownedSymbols.push_back(this->symbol());
597 }
598 uint16_t symbolCount = this->readU16();
599 std::vector<std::pair<StringFragment, int>> symbols;
600 symbols.reserve(symbolCount);
601 for (int i = 0; i < symbolCount; ++i) {
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400602 int index = this->readU16();
John Stilesb8cc6652020-10-08 09:12:07 -0400603 fSymbolTable->addWithoutOwnership(ownedSymbols[index]);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400604 }
Brian Osman1313d1a2020-09-08 10:34:30 -0400605 fSymbolTable = oldTable;
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400606 return result;
607}
608
John Stilesa6841be2020-08-06 14:11:56 -0400609} // namespace SkSL