blob: 25b61279c2d502255c24437d19bf005800b46775 [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 Nicholasc18bb512020-07-28 14:46:53 -040013#include "src/sksl/ir/SkSLBinaryExpression.h"
14#include "src/sksl/ir/SkSLBreakStatement.h"
15#include "src/sksl/ir/SkSLContinueStatement.h"
16#include "src/sksl/ir/SkSLDiscardStatement.h"
17#include "src/sksl/ir/SkSLDoStatement.h"
18#include "src/sksl/ir/SkSLEnum.h"
19#include "src/sksl/ir/SkSLExpression.h"
20#include "src/sksl/ir/SkSLExpressionStatement.h"
21#include "src/sksl/ir/SkSLField.h"
22#include "src/sksl/ir/SkSLFieldAccess.h"
23#include "src/sksl/ir/SkSLFloatLiteral.h"
24#include "src/sksl/ir/SkSLForStatement.h"
25#include "src/sksl/ir/SkSLFunctionCall.h"
26#include "src/sksl/ir/SkSLFunctionDeclaration.h"
27#include "src/sksl/ir/SkSLFunctionDefinition.h"
28#include "src/sksl/ir/SkSLIfStatement.h"
29#include "src/sksl/ir/SkSLIndexExpression.h"
John Stiles98c1f822020-09-09 14:18:53 -040030#include "src/sksl/ir/SkSLInlineMarker.h"
Ethan Nicholasc18bb512020-07-28 14:46:53 -040031#include "src/sksl/ir/SkSLIntLiteral.h"
32#include "src/sksl/ir/SkSLInterfaceBlock.h"
33#include "src/sksl/ir/SkSLModifiers.h"
34#include "src/sksl/ir/SkSLNullLiteral.h"
35#include "src/sksl/ir/SkSLPostfixExpression.h"
36#include "src/sksl/ir/SkSLPrefixExpression.h"
37#include "src/sksl/ir/SkSLProgramElement.h"
38#include "src/sksl/ir/SkSLReturnStatement.h"
39#include "src/sksl/ir/SkSLSetting.h"
40#include "src/sksl/ir/SkSLStatement.h"
41#include "src/sksl/ir/SkSLSwitchCase.h"
42#include "src/sksl/ir/SkSLSwitchStatement.h"
43#include "src/sksl/ir/SkSLSwizzle.h"
John Stiles49a547f2020-10-06 16:14:37 -040044#include "src/sksl/ir/SkSLSymbolAlias.h"
Ethan Nicholasc18bb512020-07-28 14:46:53 -040045#include "src/sksl/ir/SkSLSymbolTable.h"
46#include "src/sksl/ir/SkSLTernaryExpression.h"
47#include "src/sksl/ir/SkSLType.h"
48#include "src/sksl/ir/SkSLUnresolvedFunction.h"
49#include "src/sksl/ir/SkSLVarDeclarations.h"
Ethan Nicholasc18bb512020-07-28 14:46:53 -040050#include "src/sksl/ir/SkSLVariable.h"
51#include "src/sksl/ir/SkSLWhileStatement.h"
52
53namespace SkSL {
54
55class AutoRehydratorSymbolTable {
56public:
57 AutoRehydratorSymbolTable(Rehydrator* rehydrator)
58 : fRehydrator(rehydrator)
59 , fOldSymbols(fRehydrator->fSymbolTable) {
60 fRehydrator->fSymbolTable = fRehydrator->symbolTable();
61 }
62
63 ~AutoRehydratorSymbolTable() {
64 fRehydrator->fSymbolTable = std::move(fOldSymbols);
65 }
66
67private:
68 Rehydrator* fRehydrator;
69 std::shared_ptr<SymbolTable> fOldSymbols;
70};
71
72Layout Rehydrator::layout() {
73 switch (this->readU8()) {
74 case kBuiltinLayout_Command: {
75 Layout result;
76 result.fBuiltin = this->readS16();
77 return result;
78 }
79 case kDefaultLayout_Command:
80 return Layout();
81 case kLayout_Command: {
82 int flags = this->readU32();
83 int location = this->readS8();
84 int offset = this->readS8();
85 int binding = this->readS8();
86 int index = this->readS8();
87 int set = this->readS8();
88 int builtin = this->readS16();
89 int inputAttachmentIndex = this->readS8();
90 int format = this->readS8();
91 int primitive = this->readS8();
92 int maxVertices = this->readS8();
93 int invocations = this->readS8();
94 StringFragment marker = this->readString();
95 StringFragment when = this->readString();
96 int key = this->readS8();
97 int ctype = this->readS8();
98 return Layout(flags, location, offset, binding, index, set, builtin,
99 inputAttachmentIndex, (Layout::Format) format,
100 (Layout::Primitive) primitive, maxVertices, invocations, marker, when,
101 (Layout::Key) key, (Layout::CType) ctype);
102 }
103 default:
104 SkASSERT(false);
105 return Layout();
106 }
107}
108
109Modifiers Rehydrator::modifiers() {
110 switch (this->readU8()) {
111 case kDefaultModifiers_Command:
112 return Modifiers();
113 case kModifiers8Bit_Command: {
114 Layout l = this->layout();
115 int flags = this->readU8();
116 return Modifiers(l, flags);
117 }
118 case kModifiers_Command: {
119 Layout l = this->layout();
120 int flags = this->readS32();
121 return Modifiers(l, flags);
122 }
123 default:
124 SkASSERT(false);
125 return Modifiers();
126 }
127}
128
Ethan Nicholas041fd0a2020-10-07 16:42:04 -0400129Symbol* Rehydrator::symbol() {
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400130 int kind = this->readU8();
131 switch (kind) {
132 case kArrayType_Command: {
133 uint16_t id = this->readU16();
134 const Type* componentType = this->type();
Brian Osmane8c26082020-10-01 17:22:45 -0400135 int8_t count = this->readS8();
136 String name = componentType->name();
137 if (count == Type::kUnsizedArray) {
138 name += "[]";
139 } else {
140 name += "[" + to_string(count) + "]";
141 }
Ethan Nicholas041fd0a2020-10-07 16:42:04 -0400142 Type* result = fSymbolTable->takeOwnershipOfSymbol(
Brian Osmane8c26082020-10-01 17:22:45 -0400143 std::make_unique<Type>(name, Type::TypeKind::kArray, *componentType, count));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400144 this->addSymbol(id, result);
145 return result;
146 }
147 case kEnumType_Command: {
148 uint16_t id = this->readU16();
149 StringFragment name = this->readString();
Ethan Nicholas041fd0a2020-10-07 16:42:04 -0400150 Type* result = fSymbolTable->takeOwnershipOfSymbol(
Ethan Nicholase6592142020-09-08 10:22:09 -0400151 std::make_unique<Type>(name, Type::TypeKind::kEnum));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400152 this->addSymbol(id, result);
153 return result;
154 }
155 case kFunctionDeclaration_Command: {
156 uint16_t id = this->readU16();
157 Modifiers modifiers = this->modifiers();
158 StringFragment name = this->readString();
159 int parameterCount = this->readU8();
Ethan Nicholas041fd0a2020-10-07 16:42:04 -0400160 std::vector<Variable*> parameters;
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400161 parameters.reserve(parameterCount);
162 for (int i = 0; i < parameterCount; ++i) {
Ethan Nicholase6592142020-09-08 10:22:09 -0400163 parameters.push_back(this->symbolRef<Variable>(Symbol::Kind::kVariable));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400164 }
165 const Type* returnType = this->type();
Ethan Nicholas041fd0a2020-10-07 16:42:04 -0400166 FunctionDeclaration* result =
John Stiles3ae071e2020-08-05 15:29:29 -0400167 fSymbolTable->takeOwnershipOfSymbol(std::make_unique<FunctionDeclaration>(
Ethan Nicholased84b732020-10-08 11:45:44 -0400168 /*offset=*/-1, fModifiers.handle(modifiers), name,
169 std::move(parameters), returnType, /*builtin=*/true));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400170 this->addSymbol(id, result);
171 return result;
172 }
173 case kField_Command: {
Ethan Nicholase6592142020-09-08 10:22:09 -0400174 const Variable* owner = this->symbolRef<Variable>(Symbol::Kind::kVariable);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400175 uint8_t index = this->readU8();
Ethan Nicholas041fd0a2020-10-07 16:42:04 -0400176 Field* result = fSymbolTable->takeOwnershipOfSymbol(
Ethan Nicholase2c49992020-10-05 11:49:11 -0400177 std::make_unique<Field>(/*offset=*/-1, owner, index));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400178 return result;
179 }
180 case kNullableType_Command: {
181 uint16_t id = this->readU16();
182 const Type* base = this->type();
Ethan Nicholas041fd0a2020-10-07 16:42:04 -0400183 Type* result = fSymbolTable->takeOwnershipOfSymbol(
Ethan Nicholase6592142020-09-08 10:22:09 -0400184 std::make_unique<Type>(base->name() + "?", Type::TypeKind::kNullable, *base));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400185 this->addSymbol(id, result);
186 return result;
187 }
188 case kStructType_Command: {
189 uint16_t id = this->readU16();
190 StringFragment name = this->readString();
191 uint8_t fieldCount = this->readU8();
192 std::vector<Type::Field> fields;
193 fields.reserve(fieldCount);
194 for (int i = 0; i < fieldCount; ++i) {
195 Modifiers m = this->modifiers();
John Stilesf621e232020-08-25 13:33:02 -0400196 StringFragment fieldName = this->readString();
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400197 const Type* type = this->type();
John Stilesf621e232020-08-25 13:33:02 -0400198 fields.emplace_back(m, fieldName, type);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400199 }
Ethan Nicholas041fd0a2020-10-07 16:42:04 -0400200 Type* result = fSymbolTable->takeOwnershipOfSymbol(
John Stiles3ae071e2020-08-05 15:29:29 -0400201 std::make_unique<Type>(/*offset=*/-1, name, std::move(fields)));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400202 this->addSymbol(id, result);
203 return result;
204 }
205 case kSymbolRef_Command: {
206 uint16_t id = this->readU16();
207 SkASSERT(fSymbols.size() > id);
208 return fSymbols[id];
209 }
John Stiles49a547f2020-10-06 16:14:37 -0400210 case kSymbolAlias_Command: {
211 uint16_t id = this->readU16();
212 StringFragment name = this->readString();
Ethan Nicholas041fd0a2020-10-07 16:42:04 -0400213 Symbol* origSymbol = this->symbol();
214 SymbolAlias* symbolAlias = fSymbolTable->takeOwnershipOfSymbol(
John Stiles49a547f2020-10-06 16:14:37 -0400215 std::make_unique<SymbolAlias>(/*offset=*/-1, name, origSymbol));
216 this->addSymbol(id, symbolAlias);
217 return symbolAlias;
218 }
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400219 case kSystemType_Command: {
220 uint16_t id = this->readU16();
221 StringFragment name = this->readString();
Ethan Nicholas041fd0a2020-10-07 16:42:04 -0400222 Symbol* result = (*fSymbolTable)[name];
Ethan Nicholase6592142020-09-08 10:22:09 -0400223 SkASSERT(result && result->kind() == Symbol::Kind::kType);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400224 this->addSymbol(id, result);
225 return result;
226 }
227 case kUnresolvedFunction_Command: {
228 uint16_t id = this->readU16();
229 int length = this->readU8();
230 std::vector<const FunctionDeclaration*> functions;
231 functions.reserve(length);
232 for (int i = 0; i < length; ++i) {
233 const Symbol* f = this->symbol();
Ethan Nicholase6592142020-09-08 10:22:09 -0400234 SkASSERT(f && f->kind() == Symbol::Kind::kFunctionDeclaration);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400235 functions.push_back((const FunctionDeclaration*) f);
236 }
Ethan Nicholas041fd0a2020-10-07 16:42:04 -0400237 UnresolvedFunction* result = fSymbolTable->takeOwnershipOfSymbol(
John Stiles3ae071e2020-08-05 15:29:29 -0400238 std::make_unique<UnresolvedFunction>(std::move(functions)));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400239 this->addSymbol(id, result);
240 return result;
241 }
242 case kVariable_Command: {
243 uint16_t id = this->readU16();
Ethan Nicholas041fd0a2020-10-07 16:42:04 -0400244 ModifiersPool::Handle m = fModifiers.handle(this->modifiers());
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400245 StringFragment name = this->readString();
246 const Type* type = this->type();
247 Variable::Storage storage = (Variable::Storage) this->readU8();
Ethan Nicholas041fd0a2020-10-07 16:42:04 -0400248 Variable* result = fSymbolTable->takeOwnershipOfSymbol(std::make_unique<Variable>(
Brian Osman3887a012020-09-30 13:22:27 -0400249 /*offset=*/-1, m, name, type, /*builtin=*/true, storage));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400250 this->addSymbol(id, result);
251 return result;
252 }
253 default:
254 printf("unsupported symbol %d\n", kind);
255 SkASSERT(false);
256 return nullptr;
257 }
258}
259
260const Type* Rehydrator::type() {
261 const Symbol* result = this->symbol();
Ethan Nicholase6592142020-09-08 10:22:09 -0400262 SkASSERT(result->kind() == Symbol::Kind::kType);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400263 return (const Type*) result;
264}
265
266std::vector<std::unique_ptr<ProgramElement>> Rehydrator::elements() {
267 SkDEBUGCODE(uint8_t command = )this->readU8();
268 SkASSERT(command == kElements_Command);
269 uint8_t count = this->readU8();
270 std::vector<std::unique_ptr<ProgramElement>> result;
271 result.reserve(count);
272 for (int i = 0; i < count; ++i) {
273 result.push_back(this->element());
274 }
275 return result;
276}
277
278std::unique_ptr<ProgramElement> Rehydrator::element() {
279 int kind = this->readU8();
280 switch (kind) {
281 case Rehydrator::kEnum_Command: {
282 StringFragment typeName = this->readString();
Brian Osman1313d1a2020-09-08 10:34:30 -0400283 std::shared_ptr<SymbolTable> symbols = this->symbolTable(/*inherit=*/false);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400284 for (auto& s : symbols->fOwnedSymbols) {
Ethan Nicholase6592142020-09-08 10:22:09 -0400285 SkASSERT(s->kind() == Symbol::Kind::kVariable);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400286 Variable& v = (Variable&) *s;
287 int value = this->readS32();
Ethan Nicholas041fd0a2020-10-07 16:42:04 -0400288 v.setInitialValue(symbols->takeOwnershipOfIRNode(
289 std::make_unique<IntLiteral>(fContext, /*offset=*/-1, value)));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400290 }
291 return std::unique_ptr<ProgramElement>(new Enum(-1, typeName, std::move(symbols)));
292 }
293 case Rehydrator::kFunctionDefinition_Command: {
294 const FunctionDeclaration* decl = this->symbolRef<FunctionDeclaration>(
Ethan Nicholase6592142020-09-08 10:22:09 -0400295 Symbol::Kind::kFunctionDeclaration);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400296 std::unique_ptr<Statement> body = this->statement();
John Stilesb8e010c2020-08-11 18:05:39 -0400297 std::unordered_set<const FunctionDeclaration*> refs;
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400298 uint8_t refCount = this->readU8();
299 for (int i = 0; i < refCount; ++i) {
300 refs.insert(this->symbolRef<FunctionDeclaration>(
Ethan Nicholase6592142020-09-08 10:22:09 -0400301 Symbol::Kind::kFunctionDeclaration));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400302 }
303 FunctionDefinition* result = new FunctionDefinition(-1, *decl, std::move(body),
304 std::move(refs));
Ethan Nicholased84b732020-10-08 11:45:44 -0400305 decl->setDefinition(result);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400306 return std::unique_ptr<ProgramElement>(result);
307 }
308 case Rehydrator::kInterfaceBlock_Command: {
309 const Symbol* var = this->symbol();
Ethan Nicholase6592142020-09-08 10:22:09 -0400310 SkASSERT(var && var->kind() == Symbol::Kind::kVariable);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400311 StringFragment typeName = this->readString();
312 StringFragment instanceName = this->readString();
313 uint8_t sizeCount = this->readU8();
314 std::vector<std::unique_ptr<Expression>> sizes;
315 sizes.reserve(sizeCount);
316 for (int i = 0; i < sizeCount; ++i) {
317 sizes.push_back(this->expression());
318 }
319 return std::unique_ptr<ProgramElement>(new InterfaceBlock(-1, (Variable*) var, typeName,
320 instanceName,
321 std::move(sizes), nullptr));
322 }
323 case Rehydrator::kVarDeclarations_Command: {
Brian Osmanc0213602020-10-06 14:43:32 -0400324 std::unique_ptr<Statement> decl = this->statement();
325 return std::unique_ptr<ProgramElement>(
326 new GlobalVarDeclaration(/*offset=*/-1, std::move(decl)));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400327 }
328 default:
329 printf("unsupported element %d\n", kind);
330 SkASSERT(false);
331 return nullptr;
332 }
333}
334
335std::unique_ptr<Statement> Rehydrator::statement() {
336 int kind = this->readU8();
337 switch (kind) {
338 case Rehydrator::kBlock_Command: {
339 AutoRehydratorSymbolTable symbols(this);
340 int count = this->readU8();
John Stiles8f2a0cf2020-10-13 12:48:21 -0400341 StatementArray statements;
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400342 statements.reserve(count);
343 for (int i = 0; i < count; ++i) {
344 statements.push_back(this->statement());
345 }
346 bool isScope = this->readU8();
John Stiles8f2a0cf2020-10-13 12:48:21 -0400347 return std::make_unique<Block>(/*offset=*/-1, std::move(statements), fSymbolTable,
348 isScope);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400349 }
350 case Rehydrator::kBreak_Command:
351 return std::unique_ptr<Statement>(new BreakStatement(-1));
352 case Rehydrator::kContinue_Command:
353 return std::unique_ptr<Statement>(new ContinueStatement(-1));
354 case Rehydrator::kDiscard_Command:
355 return std::unique_ptr<Statement>(new DiscardStatement(-1));
356 case Rehydrator::kDo_Command: {
357 std::unique_ptr<Statement> stmt = this->statement();
358 std::unique_ptr<Expression> expr = this->expression();
359 return std::unique_ptr<Statement>(new DoStatement(-1, std::move(stmt),
360 std::move(expr)));
361 }
362 case Rehydrator::kExpressionStatement_Command: {
363 std::unique_ptr<Expression> expr = this->expression();
364 return std::unique_ptr<Statement>(new ExpressionStatement(std::move(expr)));
365 }
366 case Rehydrator::kFor_Command: {
367 std::unique_ptr<Statement> initializer = this->statement();
368 std::unique_ptr<Expression> test = this->expression();
369 std::unique_ptr<Expression> next = this->expression();
370 std::unique_ptr<Statement> body = this->statement();
371 std::shared_ptr<SymbolTable> symbols = this->symbolTable();
372 return std::unique_ptr<Statement>(new ForStatement(-1, std::move(initializer),
373 std::move(test), std::move(next),
374 std::move(body),
375 std::move(symbols)));
376 }
377 case Rehydrator::kIf_Command: {
378 bool isStatic = this->readU8();
379 std::unique_ptr<Expression> test = this->expression();
380 std::unique_ptr<Statement> ifTrue = this->statement();
381 std::unique_ptr<Statement> ifFalse = this->statement();
382 return std::unique_ptr<Statement>(new IfStatement(-1, isStatic, std::move(test),
383 std::move(ifTrue),
384 std::move(ifFalse)));
385 }
John Stiles98c1f822020-09-09 14:18:53 -0400386 case Rehydrator::kInlineMarker_Command: {
387 const FunctionDeclaration* funcDecl = this->symbolRef<FunctionDeclaration>(
388 Symbol::Kind::kFunctionDeclaration);
Ethan Nicholasceb62142020-10-09 16:51:18 -0400389 return std::make_unique<InlineMarker>(funcDecl);
John Stiles98c1f822020-09-09 14:18:53 -0400390 }
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400391 case Rehydrator::kReturn_Command: {
392 std::unique_ptr<Expression> expr = this->expression();
393 if (expr) {
394 return std::unique_ptr<Statement>(new ReturnStatement(std::move(expr)));
395 } else {
396 return std::unique_ptr<Statement>(new ReturnStatement(-1));
397 }
398 }
399 case Rehydrator::kSwitch_Command: {
400 bool isStatic = this->readU8();
401 AutoRehydratorSymbolTable symbols(this);
402 std::unique_ptr<Expression> expr = this->expression();
403 int caseCount = this->readU8();
404 std::vector<std::unique_ptr<SwitchCase>> cases;
405 cases.reserve(caseCount);
406 for (int i = 0; i < caseCount; ++i) {
407 std::unique_ptr<Expression> value = this->expression();
408 int statementCount = this->readU8();
John Stiles8f2a0cf2020-10-13 12:48:21 -0400409 StatementArray statements;
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400410 statements.reserve(statementCount);
411 for (int j = 0; j < statementCount; ++j) {
412 statements.push_back(this->statement());
413 }
John Stiles8f2a0cf2020-10-13 12:48:21 -0400414 cases.push_back(std::make_unique<SwitchCase>(/*offset=*/-1, std::move(value),
415 std::move(statements)));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400416 }
John Stiles8f2a0cf2020-10-13 12:48:21 -0400417 return std::make_unique<SwitchStatement>(-1, isStatic, std::move(expr),
418 std::move(cases), fSymbolTable);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400419 }
420 case Rehydrator::kVarDeclaration_Command: {
Ethan Nicholase6592142020-09-08 10:22:09 -0400421 Variable* var = this->symbolRef<Variable>(Symbol::Kind::kVariable);
Brian Osmanc0213602020-10-06 14:43:32 -0400422 const Type* baseType = this->type();
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400423 uint8_t sizeCount = this->readU8();
424 std::vector<std::unique_ptr<Expression>> sizes;
425 sizes.reserve(sizeCount);
426 for (int i = 0; i < sizeCount; ++i) {
427 sizes.push_back(this->expression());
428 }
429 std::unique_ptr<Expression> value = this->expression();
430 if (value) {
Ethan Nicholas041fd0a2020-10-07 16:42:04 -0400431 var->setInitialValue(value.get());
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400432 }
Brian Osmanc0213602020-10-06 14:43:32 -0400433 return std::unique_ptr<Statement>(
434 new VarDeclaration(var, baseType, std::move(sizes), std::move(value)));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400435 }
436 case Rehydrator::kVoid_Command:
437 return nullptr;
438 case Rehydrator::kWhile_Command: {
439 std::unique_ptr<Expression> expr = this->expression();
440 std::unique_ptr<Statement> stmt = this->statement();
441 return std::unique_ptr<Statement>(new WhileStatement(-1, std::move(expr),
442 std::move(stmt)));
443 }
444 default:
445 printf("unsupported statement %d\n", kind);
446 SkASSERT(false);
447 return nullptr;
448 }
449}
450
451std::unique_ptr<Expression> Rehydrator::expression() {
452 int kind = this->readU8();
453 switch (kind) {
454 case Rehydrator::kBinary_Command: {
455 std::unique_ptr<Expression> left = this->expression();
456 Token::Kind op = (Token::Kind) this->readU8();
457 std::unique_ptr<Expression> right = this->expression();
458 const Type* type = this->type();
Ethan Nicholas30d30222020-09-11 12:27:26 -0400459 return std::make_unique<BinaryExpression>(-1, std::move(left), op, std::move(right),
460 type);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400461 }
462 case Rehydrator::kBoolLiteral_Command: {
463 bool value = this->readU8();
Ethan Nicholas30d30222020-09-11 12:27:26 -0400464 return std::make_unique<BoolLiteral>(fContext, -1, value);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400465 }
466 case Rehydrator::kConstructor_Command: {
467 const Type* type = this->type();
468 uint8_t argCount = this->readU8();
John Stiles8e3b6be2020-10-13 11:14:08 -0400469 ExpressionArray args;
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400470 args.reserve(argCount);
471 for (int i = 0; i < argCount; ++i) {
472 args.push_back(this->expression());
473 }
Ethan Nicholas30d30222020-09-11 12:27:26 -0400474 return std::make_unique<Constructor>(-1, type, std::move(args));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400475 }
476 case Rehydrator::kFieldAccess_Command: {
477 std::unique_ptr<Expression> base = this->expression();
478 int index = this->readU8();
479 FieldAccess::OwnerKind ownerKind = (FieldAccess::OwnerKind) this->readU8();
Ethan Nicholas30d30222020-09-11 12:27:26 -0400480 return std::make_unique<FieldAccess>(std::move(base), index, ownerKind);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400481 }
482 case Rehydrator::kFloatLiteral_Command: {
483 FloatIntUnion u;
484 u.fInt = this->readS32();
Ethan Nicholas30d30222020-09-11 12:27:26 -0400485 return std::make_unique<FloatLiteral>(fContext, -1, u.fFloat);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400486 }
487 case Rehydrator::kFunctionCall_Command: {
Ethan Nicholas30d30222020-09-11 12:27:26 -0400488 const Type* type = this->type();
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400489 const FunctionDeclaration* f = this->symbolRef<FunctionDeclaration>(
Ethan Nicholase6592142020-09-08 10:22:09 -0400490 Symbol::Kind::kFunctionDeclaration);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400491 uint8_t argCount = this->readU8();
John Stiles8e3b6be2020-10-13 11:14:08 -0400492 ExpressionArray args;
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400493 args.reserve(argCount);
494 for (int i = 0; i < argCount; ++i) {
495 args.push_back(this->expression());
496 }
Ethan Nicholas0dec9922020-10-05 15:51:52 -0400497 return std::make_unique<FunctionCall>(-1, type, f, std::move(args));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400498 }
499 case Rehydrator::kIndex_Command: {
500 std::unique_ptr<Expression> base = this->expression();
501 std::unique_ptr<Expression> index = this->expression();
Ethan Nicholas30d30222020-09-11 12:27:26 -0400502 return std::make_unique<IndexExpression>(fContext, std::move(base), std::move(index));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400503 }
504 case Rehydrator::kIntLiteral_Command: {
505 int value = this->readS32();
Ethan Nicholas30d30222020-09-11 12:27:26 -0400506 return std::make_unique<IntLiteral>(fContext, -1, value);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400507 }
508 case Rehydrator::kNullLiteral_Command:
Ethan Nicholas30d30222020-09-11 12:27:26 -0400509 return std::make_unique<NullLiteral>(fContext, -1);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400510 case Rehydrator::kPostfix_Command: {
511 Token::Kind op = (Token::Kind) this->readU8();
512 std::unique_ptr<Expression> operand = this->expression();
Ethan Nicholas30d30222020-09-11 12:27:26 -0400513 return std::make_unique<PostfixExpression>(std::move(operand), op);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400514 }
515 case Rehydrator::kPrefix_Command: {
516 Token::Kind op = (Token::Kind) this->readU8();
517 std::unique_ptr<Expression> operand = this->expression();
Ethan Nicholas30d30222020-09-11 12:27:26 -0400518 return std::make_unique<PrefixExpression>(op, std::move(operand));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400519 }
520 case Rehydrator::kSetting_Command: {
521 StringFragment name = this->readString();
Ethan Nicholas01ec7e82020-10-08 12:10:12 -0400522 const Type* type = this->type();
523 return std::make_unique<Setting>(-1, name, type);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400524 }
525 case Rehydrator::kSwizzle_Command: {
526 std::unique_ptr<Expression> base = this->expression();
527 int count = this->readU8();
528 std::vector<int> components;
529 components.reserve(count);
530 for (int i = 0; i < count; ++i) {
531 components.push_back(this->readU8());
532 }
Ethan Nicholas30d30222020-09-11 12:27:26 -0400533 return std::make_unique<Swizzle>(fContext, std::move(base), std::move(components));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400534 }
535 case Rehydrator::kTernary_Command: {
536 std::unique_ptr<Expression> test = this->expression();
537 std::unique_ptr<Expression> ifTrue = this->expression();
538 std::unique_ptr<Expression> ifFalse = this->expression();
Ethan Nicholasa02ce0c2020-09-21 12:37:02 -0400539 return std::make_unique<TernaryExpression>(-1, std::move(test), std::move(ifTrue),
540 std::move(ifFalse));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400541 }
542 case Rehydrator::kVariableReference_Command: {
Ethan Nicholase6592142020-09-08 10:22:09 -0400543 const Variable* var = this->symbolRef<Variable>(Symbol::Kind::kVariable);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400544 VariableReference::RefKind refKind = (VariableReference::RefKind) this->readU8();
Brian Osman79457ef2020-09-24 15:01:27 -0400545 return std::make_unique<VariableReference>(-1, var, refKind);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400546 }
547 case Rehydrator::kVoid_Command:
548 return nullptr;
549 default:
550 printf("unsupported expression %d\n", kind);
551 SkASSERT(false);
552 return nullptr;
553 }
554}
555
Brian Osman1313d1a2020-09-08 10:34:30 -0400556std::shared_ptr<SymbolTable> Rehydrator::symbolTable(bool inherit) {
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400557 int command = this->readU8();
558 if (command == kVoid_Command) {
559 return nullptr;
560 }
561 SkASSERT(command == kSymbolTable_Command);
562 uint16_t ownedCount = this->readU16();
Brian Osman1313d1a2020-09-08 10:34:30 -0400563 std::shared_ptr<SymbolTable> oldTable = fSymbolTable;
564 std::shared_ptr<SymbolTable> result = inherit ? std::make_shared<SymbolTable>(fSymbolTable)
565 : std::make_shared<SymbolTable>(fErrors);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400566 fSymbolTable = result;
Ethan Nicholas041fd0a2020-10-07 16:42:04 -0400567 std::vector<Symbol*> ownedSymbols;
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400568 ownedSymbols.reserve(ownedCount);
569 for (int i = 0; i < ownedCount; ++i) {
570 ownedSymbols.push_back(this->symbol());
571 }
572 uint16_t symbolCount = this->readU16();
573 std::vector<std::pair<StringFragment, int>> symbols;
574 symbols.reserve(symbolCount);
575 for (int i = 0; i < symbolCount; ++i) {
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400576 int index = this->readU16();
John Stilesb8cc6652020-10-08 09:12:07 -0400577 fSymbolTable->addWithoutOwnership(ownedSymbols[index]);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400578 }
Brian Osman1313d1a2020-09-08 10:34:30 -0400579 fSymbolTable = oldTable;
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400580 return result;
581}
582
John Stilesa6841be2020-08-06 14:11:56 -0400583} // namespace SkSL