blob: 05d69dcdc21d33a81f4a97735af52cca20f58e4e [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"
50#include "src/sksl/ir/SkSLVarDeclarationsStatement.h"
51#include "src/sksl/ir/SkSLVariable.h"
52#include "src/sksl/ir/SkSLWhileStatement.h"
53
54namespace SkSL {
55
56class AutoRehydratorSymbolTable {
57public:
58 AutoRehydratorSymbolTable(Rehydrator* rehydrator)
59 : fRehydrator(rehydrator)
60 , fOldSymbols(fRehydrator->fSymbolTable) {
61 fRehydrator->fSymbolTable = fRehydrator->symbolTable();
62 }
63
64 ~AutoRehydratorSymbolTable() {
65 fRehydrator->fSymbolTable = std::move(fOldSymbols);
66 }
67
68private:
69 Rehydrator* fRehydrator;
70 std::shared_ptr<SymbolTable> fOldSymbols;
71};
72
73Layout Rehydrator::layout() {
74 switch (this->readU8()) {
75 case kBuiltinLayout_Command: {
76 Layout result;
77 result.fBuiltin = this->readS16();
78 return result;
79 }
80 case kDefaultLayout_Command:
81 return Layout();
82 case kLayout_Command: {
83 int flags = this->readU32();
84 int location = this->readS8();
85 int offset = this->readS8();
86 int binding = this->readS8();
87 int index = this->readS8();
88 int set = this->readS8();
89 int builtin = this->readS16();
90 int inputAttachmentIndex = this->readS8();
91 int format = this->readS8();
92 int primitive = this->readS8();
93 int maxVertices = this->readS8();
94 int invocations = this->readS8();
95 StringFragment marker = this->readString();
96 StringFragment when = this->readString();
97 int key = this->readS8();
98 int ctype = this->readS8();
99 return Layout(flags, location, offset, binding, index, set, builtin,
100 inputAttachmentIndex, (Layout::Format) format,
101 (Layout::Primitive) primitive, maxVertices, invocations, marker, when,
102 (Layout::Key) key, (Layout::CType) ctype);
103 }
104 default:
105 SkASSERT(false);
106 return Layout();
107 }
108}
109
110Modifiers Rehydrator::modifiers() {
111 switch (this->readU8()) {
112 case kDefaultModifiers_Command:
113 return Modifiers();
114 case kModifiers8Bit_Command: {
115 Layout l = this->layout();
116 int flags = this->readU8();
117 return Modifiers(l, flags);
118 }
119 case kModifiers_Command: {
120 Layout l = this->layout();
121 int flags = this->readS32();
122 return Modifiers(l, flags);
123 }
124 default:
125 SkASSERT(false);
126 return Modifiers();
127 }
128}
129
130const Symbol* Rehydrator::symbol() {
131 int kind = this->readU8();
132 switch (kind) {
133 case kArrayType_Command: {
134 uint16_t id = this->readU16();
135 const Type* componentType = this->type();
Brian Osmane8c26082020-10-01 17:22:45 -0400136 int8_t count = this->readS8();
137 String name = componentType->name();
138 if (count == Type::kUnsizedArray) {
139 name += "[]";
140 } else {
141 name += "[" + to_string(count) + "]";
142 }
John Stiles3ae071e2020-08-05 15:29:29 -0400143 const Type* result = fSymbolTable->takeOwnershipOfSymbol(
Brian Osmane8c26082020-10-01 17:22:45 -0400144 std::make_unique<Type>(name, Type::TypeKind::kArray, *componentType, count));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400145 this->addSymbol(id, result);
146 return result;
147 }
148 case kEnumType_Command: {
149 uint16_t id = this->readU16();
150 StringFragment name = this->readString();
John Stiles3ae071e2020-08-05 15:29:29 -0400151 const Type* result = fSymbolTable->takeOwnershipOfSymbol(
Ethan Nicholase6592142020-09-08 10:22:09 -0400152 std::make_unique<Type>(name, Type::TypeKind::kEnum));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400153 this->addSymbol(id, result);
154 return result;
155 }
156 case kFunctionDeclaration_Command: {
157 uint16_t id = this->readU16();
158 Modifiers modifiers = this->modifiers();
159 StringFragment name = this->readString();
160 int parameterCount = this->readU8();
161 std::vector<const Variable*> parameters;
162 parameters.reserve(parameterCount);
163 for (int i = 0; i < parameterCount; ++i) {
Ethan Nicholase6592142020-09-08 10:22:09 -0400164 parameters.push_back(this->symbolRef<Variable>(Symbol::Kind::kVariable));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400165 }
166 const Type* returnType = this->type();
John Stiles3ae071e2020-08-05 15:29:29 -0400167 const FunctionDeclaration* result =
168 fSymbolTable->takeOwnershipOfSymbol(std::make_unique<FunctionDeclaration>(
169 /*offset=*/-1, modifiers, name, std::move(parameters), *returnType,
170 /*builtin=*/true));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400171 this->addSymbol(id, result);
172 return result;
173 }
174 case kField_Command: {
Ethan Nicholase6592142020-09-08 10:22:09 -0400175 const Variable* owner = this->symbolRef<Variable>(Symbol::Kind::kVariable);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400176 uint8_t index = this->readU8();
John Stiles3ae071e2020-08-05 15:29:29 -0400177 const Field* result = fSymbolTable->takeOwnershipOfSymbol(
Ethan Nicholase2c49992020-10-05 11:49:11 -0400178 std::make_unique<Field>(/*offset=*/-1, owner, index));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400179 return result;
180 }
181 case kNullableType_Command: {
182 uint16_t id = this->readU16();
183 const Type* base = this->type();
John Stiles3ae071e2020-08-05 15:29:29 -0400184 const Type* result = fSymbolTable->takeOwnershipOfSymbol(
Ethan Nicholase6592142020-09-08 10:22:09 -0400185 std::make_unique<Type>(base->name() + "?", Type::TypeKind::kNullable, *base));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400186 this->addSymbol(id, result);
187 return result;
188 }
189 case kStructType_Command: {
190 uint16_t id = this->readU16();
191 StringFragment name = this->readString();
192 uint8_t fieldCount = this->readU8();
193 std::vector<Type::Field> fields;
194 fields.reserve(fieldCount);
195 for (int i = 0; i < fieldCount; ++i) {
196 Modifiers m = this->modifiers();
John Stilesf621e232020-08-25 13:33:02 -0400197 StringFragment fieldName = this->readString();
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400198 const Type* type = this->type();
John Stilesf621e232020-08-25 13:33:02 -0400199 fields.emplace_back(m, fieldName, type);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400200 }
John Stiles3ae071e2020-08-05 15:29:29 -0400201 const Type* result = fSymbolTable->takeOwnershipOfSymbol(
202 std::make_unique<Type>(/*offset=*/-1, name, std::move(fields)));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400203 this->addSymbol(id, result);
204 return result;
205 }
206 case kSymbolRef_Command: {
207 uint16_t id = this->readU16();
208 SkASSERT(fSymbols.size() > id);
209 return fSymbols[id];
210 }
John Stiles49a547f2020-10-06 16:14:37 -0400211 case kSymbolAlias_Command: {
212 uint16_t id = this->readU16();
213 StringFragment name = this->readString();
214 const Symbol* origSymbol = this->symbol();
215 const SymbolAlias* symbolAlias = fSymbolTable->takeOwnershipOfSymbol(
216 std::make_unique<SymbolAlias>(/*offset=*/-1, name, origSymbol));
217 this->addSymbol(id, symbolAlias);
218 return symbolAlias;
219 }
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400220 case kSystemType_Command: {
221 uint16_t id = this->readU16();
222 StringFragment name = this->readString();
223 const Symbol* result = (*fSymbolTable)[name];
Ethan Nicholase6592142020-09-08 10:22:09 -0400224 SkASSERT(result && result->kind() == Symbol::Kind::kType);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400225 this->addSymbol(id, result);
226 return result;
227 }
228 case kUnresolvedFunction_Command: {
229 uint16_t id = this->readU16();
230 int length = this->readU8();
231 std::vector<const FunctionDeclaration*> functions;
232 functions.reserve(length);
233 for (int i = 0; i < length; ++i) {
234 const Symbol* f = this->symbol();
Ethan Nicholase6592142020-09-08 10:22:09 -0400235 SkASSERT(f && f->kind() == Symbol::Kind::kFunctionDeclaration);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400236 functions.push_back((const FunctionDeclaration*) f);
237 }
John Stiles3ae071e2020-08-05 15:29:29 -0400238 const UnresolvedFunction* result = fSymbolTable->takeOwnershipOfSymbol(
239 std::make_unique<UnresolvedFunction>(std::move(functions)));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400240 this->addSymbol(id, result);
241 return result;
242 }
243 case kVariable_Command: {
244 uint16_t id = this->readU16();
245 Modifiers m = this->modifiers();
246 StringFragment name = this->readString();
247 const Type* type = this->type();
248 Variable::Storage storage = (Variable::Storage) this->readU8();
Brian Osman3887a012020-09-30 13:22:27 -0400249 const Variable* result = fSymbolTable->takeOwnershipOfSymbol(std::make_unique<Variable>(
250 /*offset=*/-1, m, name, type, /*builtin=*/true, storage));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400251 this->addSymbol(id, result);
252 return result;
253 }
254 default:
255 printf("unsupported symbol %d\n", kind);
256 SkASSERT(false);
257 return nullptr;
258 }
259}
260
261const Type* Rehydrator::type() {
262 const Symbol* result = this->symbol();
Ethan Nicholase6592142020-09-08 10:22:09 -0400263 SkASSERT(result->kind() == Symbol::Kind::kType);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400264 return (const Type*) result;
265}
266
267std::vector<std::unique_ptr<ProgramElement>> Rehydrator::elements() {
268 SkDEBUGCODE(uint8_t command = )this->readU8();
269 SkASSERT(command == kElements_Command);
270 uint8_t count = this->readU8();
271 std::vector<std::unique_ptr<ProgramElement>> result;
272 result.reserve(count);
273 for (int i = 0; i < count; ++i) {
274 result.push_back(this->element());
275 }
276 return result;
277}
278
279std::unique_ptr<ProgramElement> Rehydrator::element() {
280 int kind = this->readU8();
281 switch (kind) {
282 case Rehydrator::kEnum_Command: {
283 StringFragment typeName = this->readString();
Brian Osman1313d1a2020-09-08 10:34:30 -0400284 std::shared_ptr<SymbolTable> symbols = this->symbolTable(/*inherit=*/false);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400285 for (auto& s : symbols->fOwnedSymbols) {
Ethan Nicholase6592142020-09-08 10:22:09 -0400286 SkASSERT(s->kind() == Symbol::Kind::kVariable);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400287 Variable& v = (Variable&) *s;
288 int value = this->readS32();
John Stiles3ae071e2020-08-05 15:29:29 -0400289 v.fInitialValue = symbols->takeOwnershipOfIRNode(
290 std::make_unique<IntLiteral>(fContext, /*offset=*/-1, value));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400291 v.fWriteCount = 1;
292 }
293 return std::unique_ptr<ProgramElement>(new Enum(-1, typeName, std::move(symbols)));
294 }
295 case Rehydrator::kFunctionDefinition_Command: {
296 const FunctionDeclaration* decl = this->symbolRef<FunctionDeclaration>(
Ethan Nicholase6592142020-09-08 10:22:09 -0400297 Symbol::Kind::kFunctionDeclaration);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400298 std::unique_ptr<Statement> body = this->statement();
John Stilesb8e010c2020-08-11 18:05:39 -0400299 std::unordered_set<const FunctionDeclaration*> refs;
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400300 uint8_t refCount = this->readU8();
301 for (int i = 0; i < refCount; ++i) {
302 refs.insert(this->symbolRef<FunctionDeclaration>(
Ethan Nicholase6592142020-09-08 10:22:09 -0400303 Symbol::Kind::kFunctionDeclaration));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400304 }
305 FunctionDefinition* result = new FunctionDefinition(-1, *decl, std::move(body),
306 std::move(refs));
307 decl->fDefinition = result;
308 return std::unique_ptr<ProgramElement>(result);
309 }
310 case Rehydrator::kInterfaceBlock_Command: {
311 const Symbol* var = this->symbol();
Ethan Nicholase6592142020-09-08 10:22:09 -0400312 SkASSERT(var && var->kind() == Symbol::Kind::kVariable);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400313 StringFragment typeName = this->readString();
314 StringFragment instanceName = this->readString();
315 uint8_t sizeCount = this->readU8();
316 std::vector<std::unique_ptr<Expression>> sizes;
317 sizes.reserve(sizeCount);
318 for (int i = 0; i < sizeCount; ++i) {
319 sizes.push_back(this->expression());
320 }
321 return std::unique_ptr<ProgramElement>(new InterfaceBlock(-1, (Variable*) var, typeName,
322 instanceName,
323 std::move(sizes), nullptr));
324 }
325 case Rehydrator::kVarDeclarations_Command: {
326 const Type* baseType = this->type();
327 int count = this->readU8();
Brian Osman347e5dc2020-10-05 15:56:44 -0400328 std::vector<std::unique_ptr<Statement>> vars;
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400329 vars.reserve(count);
330 for (int i = 0 ; i < count; ++i) {
Brian Osman347e5dc2020-10-05 15:56:44 -0400331 vars.push_back(this->statement());
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400332 }
333 return std::unique_ptr<ProgramElement>(new VarDeclarations(-1, baseType,
334 std::move(vars)));
335 }
336 default:
337 printf("unsupported element %d\n", kind);
338 SkASSERT(false);
339 return nullptr;
340 }
341}
342
343std::unique_ptr<Statement> Rehydrator::statement() {
344 int kind = this->readU8();
345 switch (kind) {
346 case Rehydrator::kBlock_Command: {
347 AutoRehydratorSymbolTable symbols(this);
348 int count = this->readU8();
349 std::vector<std::unique_ptr<Statement>> statements;
350 statements.reserve(count);
351 for (int i = 0; i < count; ++i) {
352 statements.push_back(this->statement());
353 }
354 bool isScope = this->readU8();
355 return std::unique_ptr<Statement>(new Block(-1, std::move(statements), fSymbolTable,
356 isScope));
357 }
358 case Rehydrator::kBreak_Command:
359 return std::unique_ptr<Statement>(new BreakStatement(-1));
360 case Rehydrator::kContinue_Command:
361 return std::unique_ptr<Statement>(new ContinueStatement(-1));
362 case Rehydrator::kDiscard_Command:
363 return std::unique_ptr<Statement>(new DiscardStatement(-1));
364 case Rehydrator::kDo_Command: {
365 std::unique_ptr<Statement> stmt = this->statement();
366 std::unique_ptr<Expression> expr = this->expression();
367 return std::unique_ptr<Statement>(new DoStatement(-1, std::move(stmt),
368 std::move(expr)));
369 }
370 case Rehydrator::kExpressionStatement_Command: {
371 std::unique_ptr<Expression> expr = this->expression();
372 return std::unique_ptr<Statement>(new ExpressionStatement(std::move(expr)));
373 }
374 case Rehydrator::kFor_Command: {
375 std::unique_ptr<Statement> initializer = this->statement();
376 std::unique_ptr<Expression> test = this->expression();
377 std::unique_ptr<Expression> next = this->expression();
378 std::unique_ptr<Statement> body = this->statement();
379 std::shared_ptr<SymbolTable> symbols = this->symbolTable();
380 return std::unique_ptr<Statement>(new ForStatement(-1, std::move(initializer),
381 std::move(test), std::move(next),
382 std::move(body),
383 std::move(symbols)));
384 }
385 case Rehydrator::kIf_Command: {
386 bool isStatic = this->readU8();
387 std::unique_ptr<Expression> test = this->expression();
388 std::unique_ptr<Statement> ifTrue = this->statement();
389 std::unique_ptr<Statement> ifFalse = this->statement();
390 return std::unique_ptr<Statement>(new IfStatement(-1, isStatic, std::move(test),
391 std::move(ifTrue),
392 std::move(ifFalse)));
393 }
John Stiles98c1f822020-09-09 14:18:53 -0400394 case Rehydrator::kInlineMarker_Command: {
395 const FunctionDeclaration* funcDecl = this->symbolRef<FunctionDeclaration>(
396 Symbol::Kind::kFunctionDeclaration);
397 return std::make_unique<InlineMarker>(*funcDecl);
398 }
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400399 case Rehydrator::kReturn_Command: {
400 std::unique_ptr<Expression> expr = this->expression();
401 if (expr) {
402 return std::unique_ptr<Statement>(new ReturnStatement(std::move(expr)));
403 } else {
404 return std::unique_ptr<Statement>(new ReturnStatement(-1));
405 }
406 }
407 case Rehydrator::kSwitch_Command: {
408 bool isStatic = this->readU8();
409 AutoRehydratorSymbolTable symbols(this);
410 std::unique_ptr<Expression> expr = this->expression();
411 int caseCount = this->readU8();
412 std::vector<std::unique_ptr<SwitchCase>> cases;
413 cases.reserve(caseCount);
414 for (int i = 0; i < caseCount; ++i) {
415 std::unique_ptr<Expression> value = this->expression();
416 int statementCount = this->readU8();
417 std::vector<std::unique_ptr<Statement>> statements;
418 statements.reserve(statementCount);
419 for (int j = 0; j < statementCount; ++j) {
420 statements.push_back(this->statement());
421 }
422 cases.emplace_back(new SwitchCase(-1, std::move(value), std::move(statements)));
423 }
424 return std::unique_ptr<Statement>(new SwitchStatement(-1, isStatic, std::move(expr),
425 std::move(cases),
426 fSymbolTable));
427 }
428 case Rehydrator::kVarDeclaration_Command: {
Ethan Nicholase6592142020-09-08 10:22:09 -0400429 Variable* var = this->symbolRef<Variable>(Symbol::Kind::kVariable);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400430 uint8_t sizeCount = this->readU8();
431 std::vector<std::unique_ptr<Expression>> sizes;
432 sizes.reserve(sizeCount);
433 for (int i = 0; i < sizeCount; ++i) {
434 sizes.push_back(this->expression());
435 }
436 std::unique_ptr<Expression> value = this->expression();
437 if (value) {
438 var->fInitialValue = value.get();
439 SkASSERT(var->fWriteCount == 0);
440 ++var->fWriteCount;
441 }
442 return std::unique_ptr<Statement>(new VarDeclaration(var,
443 std::move(sizes),
444 std::move(value)));
445 }
446 case Rehydrator::kVarDeclarations_Command: {
447 const Type* baseType = this->type();
448 int count = this->readU8();
Brian Osman347e5dc2020-10-05 15:56:44 -0400449 std::vector<std::unique_ptr<Statement>> vars;
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400450 vars.reserve(count);
451 for (int i = 0 ; i < count; ++i) {
Brian Osman347e5dc2020-10-05 15:56:44 -0400452 vars.push_back(this->statement());
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400453 }
John Stilesfbd050b2020-08-03 13:21:46 -0400454 return std::make_unique<VarDeclarationsStatement>(
455 std::make_unique<VarDeclarations>(-1, baseType, std::move(vars)));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400456 }
457 case Rehydrator::kVoid_Command:
458 return nullptr;
459 case Rehydrator::kWhile_Command: {
460 std::unique_ptr<Expression> expr = this->expression();
461 std::unique_ptr<Statement> stmt = this->statement();
462 return std::unique_ptr<Statement>(new WhileStatement(-1, std::move(expr),
463 std::move(stmt)));
464 }
465 default:
466 printf("unsupported statement %d\n", kind);
467 SkASSERT(false);
468 return nullptr;
469 }
470}
471
472std::unique_ptr<Expression> Rehydrator::expression() {
473 int kind = this->readU8();
474 switch (kind) {
475 case Rehydrator::kBinary_Command: {
476 std::unique_ptr<Expression> left = this->expression();
477 Token::Kind op = (Token::Kind) this->readU8();
478 std::unique_ptr<Expression> right = this->expression();
479 const Type* type = this->type();
Ethan Nicholas30d30222020-09-11 12:27:26 -0400480 return std::make_unique<BinaryExpression>(-1, std::move(left), op, std::move(right),
481 type);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400482 }
483 case Rehydrator::kBoolLiteral_Command: {
484 bool value = this->readU8();
Ethan Nicholas30d30222020-09-11 12:27:26 -0400485 return std::make_unique<BoolLiteral>(fContext, -1, value);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400486 }
487 case Rehydrator::kConstructor_Command: {
488 const Type* type = this->type();
489 uint8_t argCount = this->readU8();
490 std::vector<std::unique_ptr<Expression>> args;
491 args.reserve(argCount);
492 for (int i = 0; i < argCount; ++i) {
493 args.push_back(this->expression());
494 }
Ethan Nicholas30d30222020-09-11 12:27:26 -0400495 return std::make_unique<Constructor>(-1, type, std::move(args));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400496 }
497 case Rehydrator::kFieldAccess_Command: {
498 std::unique_ptr<Expression> base = this->expression();
499 int index = this->readU8();
500 FieldAccess::OwnerKind ownerKind = (FieldAccess::OwnerKind) this->readU8();
Ethan Nicholas30d30222020-09-11 12:27:26 -0400501 return std::make_unique<FieldAccess>(std::move(base), index, ownerKind);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400502 }
503 case Rehydrator::kFloatLiteral_Command: {
504 FloatIntUnion u;
505 u.fInt = this->readS32();
Ethan Nicholas30d30222020-09-11 12:27:26 -0400506 return std::make_unique<FloatLiteral>(fContext, -1, u.fFloat);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400507 }
508 case Rehydrator::kFunctionCall_Command: {
Ethan Nicholas30d30222020-09-11 12:27:26 -0400509 const Type* type = this->type();
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400510 const FunctionDeclaration* f = this->symbolRef<FunctionDeclaration>(
Ethan Nicholase6592142020-09-08 10:22:09 -0400511 Symbol::Kind::kFunctionDeclaration);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400512 uint8_t argCount = this->readU8();
513 std::vector<std::unique_ptr<Expression>> args;
514 args.reserve(argCount);
515 for (int i = 0; i < argCount; ++i) {
516 args.push_back(this->expression());
517 }
Ethan Nicholas0dec9922020-10-05 15:51:52 -0400518 return std::make_unique<FunctionCall>(-1, type, f, std::move(args));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400519 }
520 case Rehydrator::kIndex_Command: {
521 std::unique_ptr<Expression> base = this->expression();
522 std::unique_ptr<Expression> index = this->expression();
Ethan Nicholas30d30222020-09-11 12:27:26 -0400523 return std::make_unique<IndexExpression>(fContext, std::move(base), std::move(index));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400524 }
525 case Rehydrator::kIntLiteral_Command: {
526 int value = this->readS32();
Ethan Nicholas30d30222020-09-11 12:27:26 -0400527 return std::make_unique<IntLiteral>(fContext, -1, value);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400528 }
529 case Rehydrator::kNullLiteral_Command:
Ethan Nicholas30d30222020-09-11 12:27:26 -0400530 return std::make_unique<NullLiteral>(fContext, -1);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400531 case Rehydrator::kPostfix_Command: {
532 Token::Kind op = (Token::Kind) this->readU8();
533 std::unique_ptr<Expression> operand = this->expression();
Ethan Nicholas30d30222020-09-11 12:27:26 -0400534 return std::make_unique<PostfixExpression>(std::move(operand), op);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400535 }
536 case Rehydrator::kPrefix_Command: {
537 Token::Kind op = (Token::Kind) this->readU8();
538 std::unique_ptr<Expression> operand = this->expression();
Ethan Nicholas30d30222020-09-11 12:27:26 -0400539 return std::make_unique<PrefixExpression>(op, std::move(operand));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400540 }
541 case Rehydrator::kSetting_Command: {
542 StringFragment name = this->readString();
543 std::unique_ptr<Expression> value = this->expression();
Ethan Nicholas30d30222020-09-11 12:27:26 -0400544 return std::make_unique<Setting>(-1, name, std::move(value));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400545 }
546 case Rehydrator::kSwizzle_Command: {
547 std::unique_ptr<Expression> base = this->expression();
548 int count = this->readU8();
549 std::vector<int> components;
550 components.reserve(count);
551 for (int i = 0; i < count; ++i) {
552 components.push_back(this->readU8());
553 }
Ethan Nicholas30d30222020-09-11 12:27:26 -0400554 return std::make_unique<Swizzle>(fContext, std::move(base), std::move(components));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400555 }
556 case Rehydrator::kTernary_Command: {
557 std::unique_ptr<Expression> test = this->expression();
558 std::unique_ptr<Expression> ifTrue = this->expression();
559 std::unique_ptr<Expression> ifFalse = this->expression();
Ethan Nicholasa02ce0c2020-09-21 12:37:02 -0400560 return std::make_unique<TernaryExpression>(-1, std::move(test), std::move(ifTrue),
561 std::move(ifFalse));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400562 }
563 case Rehydrator::kVariableReference_Command: {
Ethan Nicholase6592142020-09-08 10:22:09 -0400564 const Variable* var = this->symbolRef<Variable>(Symbol::Kind::kVariable);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400565 VariableReference::RefKind refKind = (VariableReference::RefKind) this->readU8();
Brian Osman79457ef2020-09-24 15:01:27 -0400566 return std::make_unique<VariableReference>(-1, var, refKind);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400567 }
568 case Rehydrator::kVoid_Command:
569 return nullptr;
570 default:
571 printf("unsupported expression %d\n", kind);
572 SkASSERT(false);
573 return nullptr;
574 }
575}
576
Brian Osman1313d1a2020-09-08 10:34:30 -0400577std::shared_ptr<SymbolTable> Rehydrator::symbolTable(bool inherit) {
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400578 int command = this->readU8();
579 if (command == kVoid_Command) {
580 return nullptr;
581 }
582 SkASSERT(command == kSymbolTable_Command);
583 uint16_t ownedCount = this->readU16();
Brian Osman1313d1a2020-09-08 10:34:30 -0400584 std::shared_ptr<SymbolTable> oldTable = fSymbolTable;
585 std::shared_ptr<SymbolTable> result = inherit ? std::make_shared<SymbolTable>(fSymbolTable)
586 : std::make_shared<SymbolTable>(fErrors);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400587 fSymbolTable = result;
588 std::vector<const Symbol*> ownedSymbols;
589 ownedSymbols.reserve(ownedCount);
590 for (int i = 0; i < ownedCount; ++i) {
591 ownedSymbols.push_back(this->symbol());
592 }
593 uint16_t symbolCount = this->readU16();
594 std::vector<std::pair<StringFragment, int>> symbols;
595 symbols.reserve(symbolCount);
596 for (int i = 0; i < symbolCount; ++i) {
597 StringFragment name = this->readString();
598 int index = this->readU16();
599 fSymbolTable->addWithoutOwnership(name, ownedSymbols[index]);
600 }
Brian Osman1313d1a2020-09-08 10:34:30 -0400601 fSymbolTable = oldTable;
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400602 return result;
603}
604
John Stilesa6841be2020-08-06 14:11:56 -0400605} // namespace SkSL