blob: 6471144cc87010853b60afa4bf8a6bb103cdf29c [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"
44#include "src/sksl/ir/SkSLSymbolTable.h"
45#include "src/sksl/ir/SkSLTernaryExpression.h"
46#include "src/sksl/ir/SkSLType.h"
47#include "src/sksl/ir/SkSLUnresolvedFunction.h"
48#include "src/sksl/ir/SkSLVarDeclarations.h"
49#include "src/sksl/ir/SkSLVarDeclarationsStatement.h"
50#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
129const Symbol* Rehydrator::symbol() {
130 int kind = this->readU8();
131 switch (kind) {
132 case kArrayType_Command: {
133 uint16_t id = this->readU16();
134 const Type* componentType = this->type();
135 uint8_t count = this->readU8();
John Stiles3ae071e2020-08-05 15:29:29 -0400136 const Type* result = fSymbolTable->takeOwnershipOfSymbol(
137 std::make_unique<Type>(componentType->name() + "[" + to_string(count) + "]",
Ethan Nicholase6592142020-09-08 10:22:09 -0400138 Type::TypeKind::kArray, *componentType, count));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400139 this->addSymbol(id, result);
140 return result;
141 }
142 case kEnumType_Command: {
143 uint16_t id = this->readU16();
144 StringFragment name = this->readString();
John Stiles3ae071e2020-08-05 15:29:29 -0400145 const Type* result = fSymbolTable->takeOwnershipOfSymbol(
Ethan Nicholase6592142020-09-08 10:22:09 -0400146 std::make_unique<Type>(name, Type::TypeKind::kEnum));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400147 this->addSymbol(id, result);
148 return result;
149 }
150 case kFunctionDeclaration_Command: {
151 uint16_t id = this->readU16();
152 Modifiers modifiers = this->modifiers();
153 StringFragment name = this->readString();
154 int parameterCount = this->readU8();
155 std::vector<const Variable*> parameters;
156 parameters.reserve(parameterCount);
157 for (int i = 0; i < parameterCount; ++i) {
Ethan Nicholase6592142020-09-08 10:22:09 -0400158 parameters.push_back(this->symbolRef<Variable>(Symbol::Kind::kVariable));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400159 }
160 const Type* returnType = this->type();
John Stiles3ae071e2020-08-05 15:29:29 -0400161 const FunctionDeclaration* result =
162 fSymbolTable->takeOwnershipOfSymbol(std::make_unique<FunctionDeclaration>(
163 /*offset=*/-1, modifiers, name, std::move(parameters), *returnType,
164 /*builtin=*/true));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400165 this->addSymbol(id, result);
166 return result;
167 }
168 case kField_Command: {
Ethan Nicholase6592142020-09-08 10:22:09 -0400169 const Variable* owner = this->symbolRef<Variable>(Symbol::Kind::kVariable);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400170 uint8_t index = this->readU8();
John Stiles3ae071e2020-08-05 15:29:29 -0400171 const Field* result = fSymbolTable->takeOwnershipOfSymbol(
172 std::make_unique<Field>(/*offset=*/-1, *owner, index));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400173 return result;
174 }
175 case kNullableType_Command: {
176 uint16_t id = this->readU16();
177 const Type* base = this->type();
John Stiles3ae071e2020-08-05 15:29:29 -0400178 const Type* result = fSymbolTable->takeOwnershipOfSymbol(
Ethan Nicholase6592142020-09-08 10:22:09 -0400179 std::make_unique<Type>(base->name() + "?", Type::TypeKind::kNullable, *base));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400180 this->addSymbol(id, result);
181 return result;
182 }
183 case kStructType_Command: {
184 uint16_t id = this->readU16();
185 StringFragment name = this->readString();
186 uint8_t fieldCount = this->readU8();
187 std::vector<Type::Field> fields;
188 fields.reserve(fieldCount);
189 for (int i = 0; i < fieldCount; ++i) {
190 Modifiers m = this->modifiers();
John Stilesf621e232020-08-25 13:33:02 -0400191 StringFragment fieldName = this->readString();
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400192 const Type* type = this->type();
John Stilesf621e232020-08-25 13:33:02 -0400193 fields.emplace_back(m, fieldName, type);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400194 }
John Stiles3ae071e2020-08-05 15:29:29 -0400195 const Type* result = fSymbolTable->takeOwnershipOfSymbol(
196 std::make_unique<Type>(/*offset=*/-1, name, std::move(fields)));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400197 this->addSymbol(id, result);
198 return result;
199 }
200 case kSymbolRef_Command: {
201 uint16_t id = this->readU16();
202 SkASSERT(fSymbols.size() > id);
203 return fSymbols[id];
204 }
205 case kSystemType_Command: {
206 uint16_t id = this->readU16();
207 StringFragment name = this->readString();
208 const Symbol* result = (*fSymbolTable)[name];
Ethan Nicholase6592142020-09-08 10:22:09 -0400209 SkASSERT(result && result->kind() == Symbol::Kind::kType);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400210 this->addSymbol(id, result);
211 return result;
212 }
213 case kUnresolvedFunction_Command: {
214 uint16_t id = this->readU16();
215 int length = this->readU8();
216 std::vector<const FunctionDeclaration*> functions;
217 functions.reserve(length);
218 for (int i = 0; i < length; ++i) {
219 const Symbol* f = this->symbol();
Ethan Nicholase6592142020-09-08 10:22:09 -0400220 SkASSERT(f && f->kind() == Symbol::Kind::kFunctionDeclaration);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400221 functions.push_back((const FunctionDeclaration*) f);
222 }
John Stiles3ae071e2020-08-05 15:29:29 -0400223 const UnresolvedFunction* result = fSymbolTable->takeOwnershipOfSymbol(
224 std::make_unique<UnresolvedFunction>(std::move(functions)));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400225 this->addSymbol(id, result);
226 return result;
227 }
228 case kVariable_Command: {
229 uint16_t id = this->readU16();
230 Modifiers m = this->modifiers();
231 StringFragment name = this->readString();
232 const Type* type = this->type();
233 Variable::Storage storage = (Variable::Storage) this->readU8();
John Stiles3ae071e2020-08-05 15:29:29 -0400234 const Variable* result = fSymbolTable->takeOwnershipOfSymbol(
Ethan Nicholas30d30222020-09-11 12:27:26 -0400235 std::make_unique<Variable>(/*offset=*/-1, m, name, type, storage));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400236 this->addSymbol(id, result);
237 return result;
238 }
239 default:
240 printf("unsupported symbol %d\n", kind);
241 SkASSERT(false);
242 return nullptr;
243 }
244}
245
246const Type* Rehydrator::type() {
247 const Symbol* result = this->symbol();
Ethan Nicholase6592142020-09-08 10:22:09 -0400248 SkASSERT(result->kind() == Symbol::Kind::kType);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400249 return (const Type*) result;
250}
251
252std::vector<std::unique_ptr<ProgramElement>> Rehydrator::elements() {
253 SkDEBUGCODE(uint8_t command = )this->readU8();
254 SkASSERT(command == kElements_Command);
255 uint8_t count = this->readU8();
256 std::vector<std::unique_ptr<ProgramElement>> result;
257 result.reserve(count);
258 for (int i = 0; i < count; ++i) {
259 result.push_back(this->element());
260 }
261 return result;
262}
263
264std::unique_ptr<ProgramElement> Rehydrator::element() {
265 int kind = this->readU8();
266 switch (kind) {
267 case Rehydrator::kEnum_Command: {
268 StringFragment typeName = this->readString();
Brian Osman1313d1a2020-09-08 10:34:30 -0400269 std::shared_ptr<SymbolTable> symbols = this->symbolTable(/*inherit=*/false);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400270 for (auto& s : symbols->fOwnedSymbols) {
Ethan Nicholase6592142020-09-08 10:22:09 -0400271 SkASSERT(s->kind() == Symbol::Kind::kVariable);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400272 Variable& v = (Variable&) *s;
273 int value = this->readS32();
John Stiles3ae071e2020-08-05 15:29:29 -0400274 v.fInitialValue = symbols->takeOwnershipOfIRNode(
275 std::make_unique<IntLiteral>(fContext, /*offset=*/-1, value));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400276 v.fWriteCount = 1;
277 }
278 return std::unique_ptr<ProgramElement>(new Enum(-1, typeName, std::move(symbols)));
279 }
280 case Rehydrator::kFunctionDefinition_Command: {
281 const FunctionDeclaration* decl = this->symbolRef<FunctionDeclaration>(
Ethan Nicholase6592142020-09-08 10:22:09 -0400282 Symbol::Kind::kFunctionDeclaration);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400283 std::unique_ptr<Statement> body = this->statement();
John Stilesb8e010c2020-08-11 18:05:39 -0400284 std::unordered_set<const FunctionDeclaration*> refs;
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400285 uint8_t refCount = this->readU8();
286 for (int i = 0; i < refCount; ++i) {
287 refs.insert(this->symbolRef<FunctionDeclaration>(
Ethan Nicholase6592142020-09-08 10:22:09 -0400288 Symbol::Kind::kFunctionDeclaration));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400289 }
290 FunctionDefinition* result = new FunctionDefinition(-1, *decl, std::move(body),
291 std::move(refs));
292 decl->fDefinition = result;
293 return std::unique_ptr<ProgramElement>(result);
294 }
295 case Rehydrator::kInterfaceBlock_Command: {
296 const Symbol* var = this->symbol();
Ethan Nicholase6592142020-09-08 10:22:09 -0400297 SkASSERT(var && var->kind() == Symbol::Kind::kVariable);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400298 StringFragment typeName = this->readString();
299 StringFragment instanceName = this->readString();
300 uint8_t sizeCount = this->readU8();
301 std::vector<std::unique_ptr<Expression>> sizes;
302 sizes.reserve(sizeCount);
303 for (int i = 0; i < sizeCount; ++i) {
304 sizes.push_back(this->expression());
305 }
306 return std::unique_ptr<ProgramElement>(new InterfaceBlock(-1, (Variable*) var, typeName,
307 instanceName,
308 std::move(sizes), nullptr));
309 }
310 case Rehydrator::kVarDeclarations_Command: {
311 const Type* baseType = this->type();
312 int count = this->readU8();
313 std::vector<std::unique_ptr<VarDeclaration>> vars;
314 vars.reserve(count);
315 for (int i = 0 ; i < count; ++i) {
316 std::unique_ptr<Statement> s = this->statement();
Ethan Nicholase6592142020-09-08 10:22:09 -0400317 SkASSERT(s->kind() == Statement::Kind::kVarDeclaration);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400318 vars.emplace_back((VarDeclaration*) s.release());
319 }
320 return std::unique_ptr<ProgramElement>(new VarDeclarations(-1, baseType,
321 std::move(vars)));
322 }
323 default:
324 printf("unsupported element %d\n", kind);
325 SkASSERT(false);
326 return nullptr;
327 }
328}
329
330std::unique_ptr<Statement> Rehydrator::statement() {
331 int kind = this->readU8();
332 switch (kind) {
333 case Rehydrator::kBlock_Command: {
334 AutoRehydratorSymbolTable symbols(this);
335 int count = this->readU8();
336 std::vector<std::unique_ptr<Statement>> statements;
337 statements.reserve(count);
338 for (int i = 0; i < count; ++i) {
339 statements.push_back(this->statement());
340 }
341 bool isScope = this->readU8();
342 return std::unique_ptr<Statement>(new Block(-1, std::move(statements), fSymbolTable,
343 isScope));
344 }
345 case Rehydrator::kBreak_Command:
346 return std::unique_ptr<Statement>(new BreakStatement(-1));
347 case Rehydrator::kContinue_Command:
348 return std::unique_ptr<Statement>(new ContinueStatement(-1));
349 case Rehydrator::kDiscard_Command:
350 return std::unique_ptr<Statement>(new DiscardStatement(-1));
351 case Rehydrator::kDo_Command: {
352 std::unique_ptr<Statement> stmt = this->statement();
353 std::unique_ptr<Expression> expr = this->expression();
354 return std::unique_ptr<Statement>(new DoStatement(-1, std::move(stmt),
355 std::move(expr)));
356 }
357 case Rehydrator::kExpressionStatement_Command: {
358 std::unique_ptr<Expression> expr = this->expression();
359 return std::unique_ptr<Statement>(new ExpressionStatement(std::move(expr)));
360 }
361 case Rehydrator::kFor_Command: {
362 std::unique_ptr<Statement> initializer = this->statement();
363 std::unique_ptr<Expression> test = this->expression();
364 std::unique_ptr<Expression> next = this->expression();
365 std::unique_ptr<Statement> body = this->statement();
366 std::shared_ptr<SymbolTable> symbols = this->symbolTable();
367 return std::unique_ptr<Statement>(new ForStatement(-1, std::move(initializer),
368 std::move(test), std::move(next),
369 std::move(body),
370 std::move(symbols)));
371 }
372 case Rehydrator::kIf_Command: {
373 bool isStatic = this->readU8();
374 std::unique_ptr<Expression> test = this->expression();
375 std::unique_ptr<Statement> ifTrue = this->statement();
376 std::unique_ptr<Statement> ifFalse = this->statement();
377 return std::unique_ptr<Statement>(new IfStatement(-1, isStatic, std::move(test),
378 std::move(ifTrue),
379 std::move(ifFalse)));
380 }
John Stiles98c1f822020-09-09 14:18:53 -0400381 case Rehydrator::kInlineMarker_Command: {
382 const FunctionDeclaration* funcDecl = this->symbolRef<FunctionDeclaration>(
383 Symbol::Kind::kFunctionDeclaration);
384 return std::make_unique<InlineMarker>(*funcDecl);
385 }
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400386 case Rehydrator::kReturn_Command: {
387 std::unique_ptr<Expression> expr = this->expression();
388 if (expr) {
389 return std::unique_ptr<Statement>(new ReturnStatement(std::move(expr)));
390 } else {
391 return std::unique_ptr<Statement>(new ReturnStatement(-1));
392 }
393 }
394 case Rehydrator::kSwitch_Command: {
395 bool isStatic = this->readU8();
396 AutoRehydratorSymbolTable symbols(this);
397 std::unique_ptr<Expression> expr = this->expression();
398 int caseCount = this->readU8();
399 std::vector<std::unique_ptr<SwitchCase>> cases;
400 cases.reserve(caseCount);
401 for (int i = 0; i < caseCount; ++i) {
402 std::unique_ptr<Expression> value = this->expression();
403 int statementCount = this->readU8();
404 std::vector<std::unique_ptr<Statement>> statements;
405 statements.reserve(statementCount);
406 for (int j = 0; j < statementCount; ++j) {
407 statements.push_back(this->statement());
408 }
409 cases.emplace_back(new SwitchCase(-1, std::move(value), std::move(statements)));
410 }
411 return std::unique_ptr<Statement>(new SwitchStatement(-1, isStatic, std::move(expr),
412 std::move(cases),
413 fSymbolTable));
414 }
415 case Rehydrator::kVarDeclaration_Command: {
Ethan Nicholase6592142020-09-08 10:22:09 -0400416 Variable* var = this->symbolRef<Variable>(Symbol::Kind::kVariable);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400417 uint8_t sizeCount = this->readU8();
418 std::vector<std::unique_ptr<Expression>> sizes;
419 sizes.reserve(sizeCount);
420 for (int i = 0; i < sizeCount; ++i) {
421 sizes.push_back(this->expression());
422 }
423 std::unique_ptr<Expression> value = this->expression();
424 if (value) {
425 var->fInitialValue = value.get();
426 SkASSERT(var->fWriteCount == 0);
427 ++var->fWriteCount;
428 }
429 return std::unique_ptr<Statement>(new VarDeclaration(var,
430 std::move(sizes),
431 std::move(value)));
432 }
433 case Rehydrator::kVarDeclarations_Command: {
434 const Type* baseType = this->type();
435 int count = this->readU8();
436 std::vector<std::unique_ptr<VarDeclaration>> vars;
437 vars.reserve(count);
438 for (int i = 0 ; i < count; ++i) {
439 std::unique_ptr<Statement> s = this->statement();
Ethan Nicholase6592142020-09-08 10:22:09 -0400440 SkASSERT(s->kind() == Statement::Kind::kVarDeclaration);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400441 vars.emplace_back((VarDeclaration*) s.release());
442 }
John Stilesfbd050b2020-08-03 13:21:46 -0400443 return std::make_unique<VarDeclarationsStatement>(
444 std::make_unique<VarDeclarations>(-1, baseType, std::move(vars)));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400445 }
446 case Rehydrator::kVoid_Command:
447 return nullptr;
448 case Rehydrator::kWhile_Command: {
449 std::unique_ptr<Expression> expr = this->expression();
450 std::unique_ptr<Statement> stmt = this->statement();
451 return std::unique_ptr<Statement>(new WhileStatement(-1, std::move(expr),
452 std::move(stmt)));
453 }
454 default:
455 printf("unsupported statement %d\n", kind);
456 SkASSERT(false);
457 return nullptr;
458 }
459}
460
461std::unique_ptr<Expression> Rehydrator::expression() {
462 int kind = this->readU8();
463 switch (kind) {
464 case Rehydrator::kBinary_Command: {
465 std::unique_ptr<Expression> left = this->expression();
466 Token::Kind op = (Token::Kind) this->readU8();
467 std::unique_ptr<Expression> right = this->expression();
468 const Type* type = this->type();
Ethan Nicholas30d30222020-09-11 12:27:26 -0400469 return std::make_unique<BinaryExpression>(-1, std::move(left), op, std::move(right),
470 type);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400471 }
472 case Rehydrator::kBoolLiteral_Command: {
473 bool value = this->readU8();
Ethan Nicholas30d30222020-09-11 12:27:26 -0400474 return std::make_unique<BoolLiteral>(fContext, -1, value);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400475 }
476 case Rehydrator::kConstructor_Command: {
477 const Type* type = this->type();
478 uint8_t argCount = this->readU8();
479 std::vector<std::unique_ptr<Expression>> args;
480 args.reserve(argCount);
481 for (int i = 0; i < argCount; ++i) {
482 args.push_back(this->expression());
483 }
Ethan Nicholas30d30222020-09-11 12:27:26 -0400484 return std::make_unique<Constructor>(-1, type, std::move(args));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400485 }
486 case Rehydrator::kFieldAccess_Command: {
487 std::unique_ptr<Expression> base = this->expression();
488 int index = this->readU8();
489 FieldAccess::OwnerKind ownerKind = (FieldAccess::OwnerKind) this->readU8();
Ethan Nicholas30d30222020-09-11 12:27:26 -0400490 return std::make_unique<FieldAccess>(std::move(base), index, ownerKind);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400491 }
492 case Rehydrator::kFloatLiteral_Command: {
493 FloatIntUnion u;
494 u.fInt = this->readS32();
Ethan Nicholas30d30222020-09-11 12:27:26 -0400495 return std::make_unique<FloatLiteral>(fContext, -1, u.fFloat);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400496 }
497 case Rehydrator::kFunctionCall_Command: {
Ethan Nicholas30d30222020-09-11 12:27:26 -0400498 const Type* type = this->type();
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400499 const FunctionDeclaration* f = this->symbolRef<FunctionDeclaration>(
Ethan Nicholase6592142020-09-08 10:22:09 -0400500 Symbol::Kind::kFunctionDeclaration);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400501 uint8_t argCount = this->readU8();
502 std::vector<std::unique_ptr<Expression>> args;
503 args.reserve(argCount);
504 for (int i = 0; i < argCount; ++i) {
505 args.push_back(this->expression());
506 }
Ethan Nicholase6592142020-09-08 10:22:09 -0400507 return std::make_unique<FunctionCall>(-1, type, *f, std::move(args));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400508 }
509 case Rehydrator::kIndex_Command: {
510 std::unique_ptr<Expression> base = this->expression();
511 std::unique_ptr<Expression> index = this->expression();
Ethan Nicholas30d30222020-09-11 12:27:26 -0400512 return std::make_unique<IndexExpression>(fContext, std::move(base), std::move(index));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400513 }
514 case Rehydrator::kIntLiteral_Command: {
515 int value = this->readS32();
Ethan Nicholas30d30222020-09-11 12:27:26 -0400516 return std::make_unique<IntLiteral>(fContext, -1, value);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400517 }
518 case Rehydrator::kNullLiteral_Command:
Ethan Nicholas30d30222020-09-11 12:27:26 -0400519 return std::make_unique<NullLiteral>(fContext, -1);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400520 case Rehydrator::kPostfix_Command: {
521 Token::Kind op = (Token::Kind) this->readU8();
522 std::unique_ptr<Expression> operand = this->expression();
Ethan Nicholas30d30222020-09-11 12:27:26 -0400523 return std::make_unique<PostfixExpression>(std::move(operand), op);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400524 }
525 case Rehydrator::kPrefix_Command: {
526 Token::Kind op = (Token::Kind) this->readU8();
527 std::unique_ptr<Expression> operand = this->expression();
Ethan Nicholas30d30222020-09-11 12:27:26 -0400528 return std::make_unique<PrefixExpression>(op, std::move(operand));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400529 }
530 case Rehydrator::kSetting_Command: {
531 StringFragment name = this->readString();
532 std::unique_ptr<Expression> value = this->expression();
Ethan Nicholas30d30222020-09-11 12:27:26 -0400533 return std::make_unique<Setting>(-1, name, std::move(value));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400534 }
535 case Rehydrator::kSwizzle_Command: {
536 std::unique_ptr<Expression> base = this->expression();
537 int count = this->readU8();
538 std::vector<int> components;
539 components.reserve(count);
540 for (int i = 0; i < count; ++i) {
541 components.push_back(this->readU8());
542 }
Ethan Nicholas30d30222020-09-11 12:27:26 -0400543 return std::make_unique<Swizzle>(fContext, std::move(base), std::move(components));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400544 }
545 case Rehydrator::kTernary_Command: {
546 std::unique_ptr<Expression> test = this->expression();
547 std::unique_ptr<Expression> ifTrue = this->expression();
548 std::unique_ptr<Expression> ifFalse = this->expression();
Ethan Nicholasa02ce0c2020-09-21 12:37:02 -0400549 return std::make_unique<TernaryExpression>(-1, std::move(test), std::move(ifTrue),
550 std::move(ifFalse));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400551 }
552 case Rehydrator::kVariableReference_Command: {
Ethan Nicholase6592142020-09-08 10:22:09 -0400553 const Variable* var = this->symbolRef<Variable>(Symbol::Kind::kVariable);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400554 VariableReference::RefKind refKind = (VariableReference::RefKind) this->readU8();
Ethan Nicholas30d30222020-09-11 12:27:26 -0400555 return std::make_unique<VariableReference>(-1, *var, refKind);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400556 }
557 case Rehydrator::kVoid_Command:
558 return nullptr;
559 default:
560 printf("unsupported expression %d\n", kind);
561 SkASSERT(false);
562 return nullptr;
563 }
564}
565
Brian Osman1313d1a2020-09-08 10:34:30 -0400566std::shared_ptr<SymbolTable> Rehydrator::symbolTable(bool inherit) {
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400567 int command = this->readU8();
568 if (command == kVoid_Command) {
569 return nullptr;
570 }
571 SkASSERT(command == kSymbolTable_Command);
572 uint16_t ownedCount = this->readU16();
Brian Osman1313d1a2020-09-08 10:34:30 -0400573 std::shared_ptr<SymbolTable> oldTable = fSymbolTable;
574 std::shared_ptr<SymbolTable> result = inherit ? std::make_shared<SymbolTable>(fSymbolTable)
575 : std::make_shared<SymbolTable>(fErrors);
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400576 fSymbolTable = result;
577 std::vector<const Symbol*> ownedSymbols;
578 ownedSymbols.reserve(ownedCount);
579 for (int i = 0; i < ownedCount; ++i) {
580 ownedSymbols.push_back(this->symbol());
581 }
582 uint16_t symbolCount = this->readU16();
583 std::vector<std::pair<StringFragment, int>> symbols;
584 symbols.reserve(symbolCount);
585 for (int i = 0; i < symbolCount; ++i) {
586 StringFragment name = this->readString();
587 int index = this->readU16();
588 fSymbolTable->addWithoutOwnership(name, ownedSymbols[index]);
589 }
Brian Osman1313d1a2020-09-08 10:34:30 -0400590 fSymbolTable = oldTable;
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400591 return result;
592}
593
John Stilesa6841be2020-08-06 14:11:56 -0400594} // namespace SkSL