blob: 220bf198cbdbcd4b8488d77be666a5e053becb4f [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>
Ethan Nicholasc18bb512020-07-28 14:46:53 -040011#include "src/sksl/ir/SkSLBinaryExpression.h"
12#include "src/sksl/ir/SkSLBreakStatement.h"
13#include "src/sksl/ir/SkSLContinueStatement.h"
14#include "src/sksl/ir/SkSLDiscardStatement.h"
15#include "src/sksl/ir/SkSLDoStatement.h"
16#include "src/sksl/ir/SkSLEnum.h"
17#include "src/sksl/ir/SkSLExpression.h"
18#include "src/sksl/ir/SkSLExpressionStatement.h"
19#include "src/sksl/ir/SkSLField.h"
20#include "src/sksl/ir/SkSLFieldAccess.h"
21#include "src/sksl/ir/SkSLFloatLiteral.h"
22#include "src/sksl/ir/SkSLForStatement.h"
23#include "src/sksl/ir/SkSLFunctionCall.h"
24#include "src/sksl/ir/SkSLFunctionDeclaration.h"
25#include "src/sksl/ir/SkSLFunctionDefinition.h"
26#include "src/sksl/ir/SkSLIfStatement.h"
27#include "src/sksl/ir/SkSLIndexExpression.h"
28#include "src/sksl/ir/SkSLIntLiteral.h"
29#include "src/sksl/ir/SkSLInterfaceBlock.h"
30#include "src/sksl/ir/SkSLModifiers.h"
31#include "src/sksl/ir/SkSLNullLiteral.h"
32#include "src/sksl/ir/SkSLPostfixExpression.h"
33#include "src/sksl/ir/SkSLPrefixExpression.h"
34#include "src/sksl/ir/SkSLProgramElement.h"
35#include "src/sksl/ir/SkSLReturnStatement.h"
36#include "src/sksl/ir/SkSLSetting.h"
37#include "src/sksl/ir/SkSLStatement.h"
38#include "src/sksl/ir/SkSLSwitchCase.h"
39#include "src/sksl/ir/SkSLSwitchStatement.h"
40#include "src/sksl/ir/SkSLSwizzle.h"
41#include "src/sksl/ir/SkSLSymbolTable.h"
42#include "src/sksl/ir/SkSLTernaryExpression.h"
43#include "src/sksl/ir/SkSLType.h"
44#include "src/sksl/ir/SkSLUnresolvedFunction.h"
45#include "src/sksl/ir/SkSLVarDeclarations.h"
46#include "src/sksl/ir/SkSLVarDeclarationsStatement.h"
47#include "src/sksl/ir/SkSLVariable.h"
48#include "src/sksl/ir/SkSLWhileStatement.h"
49
50namespace SkSL {
51
52class AutoRehydratorSymbolTable {
53public:
54 AutoRehydratorSymbolTable(Rehydrator* rehydrator)
55 : fRehydrator(rehydrator)
56 , fOldSymbols(fRehydrator->fSymbolTable) {
57 fRehydrator->fSymbolTable = fRehydrator->symbolTable();
58 }
59
60 ~AutoRehydratorSymbolTable() {
61 fRehydrator->fSymbolTable = std::move(fOldSymbols);
62 }
63
64private:
65 Rehydrator* fRehydrator;
66 std::shared_ptr<SymbolTable> fOldSymbols;
67};
68
69Layout Rehydrator::layout() {
70 switch (this->readU8()) {
71 case kBuiltinLayout_Command: {
72 Layout result;
73 result.fBuiltin = this->readS16();
74 return result;
75 }
76 case kDefaultLayout_Command:
77 return Layout();
78 case kLayout_Command: {
79 int flags = this->readU32();
80 int location = this->readS8();
81 int offset = this->readS8();
82 int binding = this->readS8();
83 int index = this->readS8();
84 int set = this->readS8();
85 int builtin = this->readS16();
86 int inputAttachmentIndex = this->readS8();
87 int format = this->readS8();
88 int primitive = this->readS8();
89 int maxVertices = this->readS8();
90 int invocations = this->readS8();
91 StringFragment marker = this->readString();
92 StringFragment when = this->readString();
93 int key = this->readS8();
94 int ctype = this->readS8();
95 return Layout(flags, location, offset, binding, index, set, builtin,
96 inputAttachmentIndex, (Layout::Format) format,
97 (Layout::Primitive) primitive, maxVertices, invocations, marker, when,
98 (Layout::Key) key, (Layout::CType) ctype);
99 }
100 default:
101 SkASSERT(false);
102 return Layout();
103 }
104}
105
106Modifiers Rehydrator::modifiers() {
107 switch (this->readU8()) {
108 case kDefaultModifiers_Command:
109 return Modifiers();
110 case kModifiers8Bit_Command: {
111 Layout l = this->layout();
112 int flags = this->readU8();
113 return Modifiers(l, flags);
114 }
115 case kModifiers_Command: {
116 Layout l = this->layout();
117 int flags = this->readS32();
118 return Modifiers(l, flags);
119 }
120 default:
121 SkASSERT(false);
122 return Modifiers();
123 }
124}
125
126const Symbol* Rehydrator::symbol() {
127 int kind = this->readU8();
128 switch (kind) {
129 case kArrayType_Command: {
130 uint16_t id = this->readU16();
131 const Type* componentType = this->type();
132 uint8_t count = this->readU8();
John Stiles3ae071e2020-08-05 15:29:29 -0400133 const Type* result = fSymbolTable->takeOwnershipOfSymbol(
134 std::make_unique<Type>(componentType->name() + "[" + to_string(count) + "]",
135 Type::kArray_Kind, *componentType, count));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400136 this->addSymbol(id, result);
137 return result;
138 }
139 case kEnumType_Command: {
140 uint16_t id = this->readU16();
141 StringFragment name = this->readString();
John Stiles3ae071e2020-08-05 15:29:29 -0400142 const Type* result = fSymbolTable->takeOwnershipOfSymbol(
143 std::make_unique<Type>(name, Type::kEnum_Kind));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400144 this->addSymbol(id, result);
145 return result;
146 }
147 case kFunctionDeclaration_Command: {
148 uint16_t id = this->readU16();
149 Modifiers modifiers = this->modifiers();
150 StringFragment name = this->readString();
151 int parameterCount = this->readU8();
152 std::vector<const Variable*> parameters;
153 parameters.reserve(parameterCount);
154 for (int i = 0; i < parameterCount; ++i) {
155 parameters.push_back(this->symbolRef<Variable>(Symbol::kVariable_Kind));
156 }
157 const Type* returnType = this->type();
John Stiles3ae071e2020-08-05 15:29:29 -0400158 const FunctionDeclaration* result =
159 fSymbolTable->takeOwnershipOfSymbol(std::make_unique<FunctionDeclaration>(
160 /*offset=*/-1, modifiers, name, std::move(parameters), *returnType,
161 /*builtin=*/true));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400162 this->addSymbol(id, result);
163 return result;
164 }
165 case kField_Command: {
166 const Variable* owner = this->symbolRef<Variable>(Symbol::kVariable_Kind);
167 uint8_t index = this->readU8();
John Stiles3ae071e2020-08-05 15:29:29 -0400168 const Field* result = fSymbolTable->takeOwnershipOfSymbol(
169 std::make_unique<Field>(/*offset=*/-1, *owner, index));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400170 return result;
171 }
172 case kNullableType_Command: {
173 uint16_t id = this->readU16();
174 const Type* base = this->type();
John Stiles3ae071e2020-08-05 15:29:29 -0400175 const Type* result = fSymbolTable->takeOwnershipOfSymbol(
176 std::make_unique<Type>(base->name() + "?", Type::kNullable_Kind, *base));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400177 this->addSymbol(id, result);
178 return result;
179 }
180 case kStructType_Command: {
181 uint16_t id = this->readU16();
182 StringFragment name = this->readString();
183 uint8_t fieldCount = this->readU8();
184 std::vector<Type::Field> fields;
185 fields.reserve(fieldCount);
186 for (int i = 0; i < fieldCount; ++i) {
187 Modifiers m = this->modifiers();
188 StringFragment name = this->readString();
189 const Type* type = this->type();
190 fields.emplace_back(m, name, type);
191 }
John Stiles3ae071e2020-08-05 15:29:29 -0400192 const Type* result = fSymbolTable->takeOwnershipOfSymbol(
193 std::make_unique<Type>(/*offset=*/-1, name, std::move(fields)));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400194 this->addSymbol(id, result);
195 return result;
196 }
197 case kSymbolRef_Command: {
198 uint16_t id = this->readU16();
199 SkASSERT(fSymbols.size() > id);
200 return fSymbols[id];
201 }
202 case kSystemType_Command: {
203 uint16_t id = this->readU16();
204 StringFragment name = this->readString();
205 const Symbol* result = (*fSymbolTable)[name];
206 SkASSERT(result && result->fKind == Symbol::kType_Kind);
207 this->addSymbol(id, result);
208 return result;
209 }
210 case kUnresolvedFunction_Command: {
211 uint16_t id = this->readU16();
212 int length = this->readU8();
213 std::vector<const FunctionDeclaration*> functions;
214 functions.reserve(length);
215 for (int i = 0; i < length; ++i) {
216 const Symbol* f = this->symbol();
217 SkASSERT(f && f->fKind == Symbol::kFunctionDeclaration_Kind);
218 functions.push_back((const FunctionDeclaration*) f);
219 }
John Stiles3ae071e2020-08-05 15:29:29 -0400220 const UnresolvedFunction* result = fSymbolTable->takeOwnershipOfSymbol(
221 std::make_unique<UnresolvedFunction>(std::move(functions)));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400222 this->addSymbol(id, result);
223 return result;
224 }
225 case kVariable_Command: {
226 uint16_t id = this->readU16();
227 Modifiers m = this->modifiers();
228 StringFragment name = this->readString();
229 const Type* type = this->type();
230 Variable::Storage storage = (Variable::Storage) this->readU8();
John Stiles3ae071e2020-08-05 15:29:29 -0400231 const Variable* result = fSymbolTable->takeOwnershipOfSymbol(
232 std::make_unique<Variable>(/*offset=*/-1, m, name, *type, storage));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400233 this->addSymbol(id, result);
234 return result;
235 }
236 default:
237 printf("unsupported symbol %d\n", kind);
238 SkASSERT(false);
239 return nullptr;
240 }
241}
242
243const Type* Rehydrator::type() {
244 const Symbol* result = this->symbol();
245 SkASSERT(result->fKind == Symbol::kType_Kind);
246 return (const Type*) result;
247}
248
249std::vector<std::unique_ptr<ProgramElement>> Rehydrator::elements() {
250 SkDEBUGCODE(uint8_t command = )this->readU8();
251 SkASSERT(command == kElements_Command);
252 uint8_t count = this->readU8();
253 std::vector<std::unique_ptr<ProgramElement>> result;
254 result.reserve(count);
255 for (int i = 0; i < count; ++i) {
256 result.push_back(this->element());
257 }
258 return result;
259}
260
261std::unique_ptr<ProgramElement> Rehydrator::element() {
262 int kind = this->readU8();
263 switch (kind) {
264 case Rehydrator::kEnum_Command: {
265 StringFragment typeName = this->readString();
266 std::shared_ptr<SymbolTable> symbols = this->symbolTable();
267 for (auto& s : symbols->fOwnedSymbols) {
268 SkASSERT(s->fKind == Symbol::kVariable_Kind);
269 Variable& v = (Variable&) *s;
270 int value = this->readS32();
John Stiles3ae071e2020-08-05 15:29:29 -0400271 v.fInitialValue = symbols->takeOwnershipOfIRNode(
272 std::make_unique<IntLiteral>(fContext, /*offset=*/-1, value));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400273 v.fWriteCount = 1;
274 }
275 return std::unique_ptr<ProgramElement>(new Enum(-1, typeName, std::move(symbols)));
276 }
277 case Rehydrator::kFunctionDefinition_Command: {
278 const FunctionDeclaration* decl = this->symbolRef<FunctionDeclaration>(
279 Symbol::kFunctionDeclaration_Kind);
280 std::unique_ptr<Statement> body = this->statement();
281 std::set<const FunctionDeclaration*> refs;
282 uint8_t refCount = this->readU8();
283 for (int i = 0; i < refCount; ++i) {
284 refs.insert(this->symbolRef<FunctionDeclaration>(
285 Symbol::kFunctionDeclaration_Kind));
286 }
287 FunctionDefinition* result = new FunctionDefinition(-1, *decl, std::move(body),
288 std::move(refs));
289 decl->fDefinition = result;
290 return std::unique_ptr<ProgramElement>(result);
291 }
292 case Rehydrator::kInterfaceBlock_Command: {
293 const Symbol* var = this->symbol();
294 SkASSERT(var && var->fKind == Symbol::kVariable_Kind);
295 StringFragment typeName = this->readString();
296 StringFragment instanceName = this->readString();
297 uint8_t sizeCount = this->readU8();
298 std::vector<std::unique_ptr<Expression>> sizes;
299 sizes.reserve(sizeCount);
300 for (int i = 0; i < sizeCount; ++i) {
301 sizes.push_back(this->expression());
302 }
303 return std::unique_ptr<ProgramElement>(new InterfaceBlock(-1, (Variable*) var, typeName,
304 instanceName,
305 std::move(sizes), nullptr));
306 }
307 case Rehydrator::kVarDeclarations_Command: {
308 const Type* baseType = this->type();
309 int count = this->readU8();
310 std::vector<std::unique_ptr<VarDeclaration>> vars;
311 vars.reserve(count);
312 for (int i = 0 ; i < count; ++i) {
313 std::unique_ptr<Statement> s = this->statement();
314 SkASSERT(s->fKind == Statement::kVarDeclaration_Kind);
315 vars.emplace_back((VarDeclaration*) s.release());
316 }
317 return std::unique_ptr<ProgramElement>(new VarDeclarations(-1, baseType,
318 std::move(vars)));
319 }
320 default:
321 printf("unsupported element %d\n", kind);
322 SkASSERT(false);
323 return nullptr;
324 }
325}
326
327std::unique_ptr<Statement> Rehydrator::statement() {
328 int kind = this->readU8();
329 switch (kind) {
330 case Rehydrator::kBlock_Command: {
331 AutoRehydratorSymbolTable symbols(this);
332 int count = this->readU8();
333 std::vector<std::unique_ptr<Statement>> statements;
334 statements.reserve(count);
335 for (int i = 0; i < count; ++i) {
336 statements.push_back(this->statement());
337 }
338 bool isScope = this->readU8();
339 return std::unique_ptr<Statement>(new Block(-1, std::move(statements), fSymbolTable,
340 isScope));
341 }
342 case Rehydrator::kBreak_Command:
343 return std::unique_ptr<Statement>(new BreakStatement(-1));
344 case Rehydrator::kContinue_Command:
345 return std::unique_ptr<Statement>(new ContinueStatement(-1));
346 case Rehydrator::kDiscard_Command:
347 return std::unique_ptr<Statement>(new DiscardStatement(-1));
348 case Rehydrator::kDo_Command: {
349 std::unique_ptr<Statement> stmt = this->statement();
350 std::unique_ptr<Expression> expr = this->expression();
351 return std::unique_ptr<Statement>(new DoStatement(-1, std::move(stmt),
352 std::move(expr)));
353 }
354 case Rehydrator::kExpressionStatement_Command: {
355 std::unique_ptr<Expression> expr = this->expression();
356 return std::unique_ptr<Statement>(new ExpressionStatement(std::move(expr)));
357 }
358 case Rehydrator::kFor_Command: {
359 std::unique_ptr<Statement> initializer = this->statement();
360 std::unique_ptr<Expression> test = this->expression();
361 std::unique_ptr<Expression> next = this->expression();
362 std::unique_ptr<Statement> body = this->statement();
363 std::shared_ptr<SymbolTable> symbols = this->symbolTable();
364 return std::unique_ptr<Statement>(new ForStatement(-1, std::move(initializer),
365 std::move(test), std::move(next),
366 std::move(body),
367 std::move(symbols)));
368 }
369 case Rehydrator::kIf_Command: {
370 bool isStatic = this->readU8();
371 std::unique_ptr<Expression> test = this->expression();
372 std::unique_ptr<Statement> ifTrue = this->statement();
373 std::unique_ptr<Statement> ifFalse = this->statement();
374 return std::unique_ptr<Statement>(new IfStatement(-1, isStatic, std::move(test),
375 std::move(ifTrue),
376 std::move(ifFalse)));
377 }
378 case Rehydrator::kReturn_Command: {
379 std::unique_ptr<Expression> expr = this->expression();
380 if (expr) {
381 return std::unique_ptr<Statement>(new ReturnStatement(std::move(expr)));
382 } else {
383 return std::unique_ptr<Statement>(new ReturnStatement(-1));
384 }
385 }
386 case Rehydrator::kSwitch_Command: {
387 bool isStatic = this->readU8();
388 AutoRehydratorSymbolTable symbols(this);
389 std::unique_ptr<Expression> expr = this->expression();
390 int caseCount = this->readU8();
391 std::vector<std::unique_ptr<SwitchCase>> cases;
392 cases.reserve(caseCount);
393 for (int i = 0; i < caseCount; ++i) {
394 std::unique_ptr<Expression> value = this->expression();
395 int statementCount = this->readU8();
396 std::vector<std::unique_ptr<Statement>> statements;
397 statements.reserve(statementCount);
398 for (int j = 0; j < statementCount; ++j) {
399 statements.push_back(this->statement());
400 }
401 cases.emplace_back(new SwitchCase(-1, std::move(value), std::move(statements)));
402 }
403 return std::unique_ptr<Statement>(new SwitchStatement(-1, isStatic, std::move(expr),
404 std::move(cases),
405 fSymbolTable));
406 }
407 case Rehydrator::kVarDeclaration_Command: {
408 Variable* var = this->symbolRef<Variable>(Symbol::kVariable_Kind);
409 uint8_t sizeCount = this->readU8();
410 std::vector<std::unique_ptr<Expression>> sizes;
411 sizes.reserve(sizeCount);
412 for (int i = 0; i < sizeCount; ++i) {
413 sizes.push_back(this->expression());
414 }
415 std::unique_ptr<Expression> value = this->expression();
416 if (value) {
417 var->fInitialValue = value.get();
418 SkASSERT(var->fWriteCount == 0);
419 ++var->fWriteCount;
420 }
421 return std::unique_ptr<Statement>(new VarDeclaration(var,
422 std::move(sizes),
423 std::move(value)));
424 }
425 case Rehydrator::kVarDeclarations_Command: {
426 const Type* baseType = this->type();
427 int count = this->readU8();
428 std::vector<std::unique_ptr<VarDeclaration>> vars;
429 vars.reserve(count);
430 for (int i = 0 ; i < count; ++i) {
431 std::unique_ptr<Statement> s = this->statement();
432 SkASSERT(s->fKind == Statement::kVarDeclaration_Kind);
433 vars.emplace_back((VarDeclaration*) s.release());
434 }
John Stilesfbd050b2020-08-03 13:21:46 -0400435 return std::make_unique<VarDeclarationsStatement>(
436 std::make_unique<VarDeclarations>(-1, baseType, std::move(vars)));
Ethan Nicholasc18bb512020-07-28 14:46:53 -0400437 }
438 case Rehydrator::kVoid_Command:
439 return nullptr;
440 case Rehydrator::kWhile_Command: {
441 std::unique_ptr<Expression> expr = this->expression();
442 std::unique_ptr<Statement> stmt = this->statement();
443 return std::unique_ptr<Statement>(new WhileStatement(-1, std::move(expr),
444 std::move(stmt)));
445 }
446 default:
447 printf("unsupported statement %d\n", kind);
448 SkASSERT(false);
449 return nullptr;
450 }
451}
452
453std::unique_ptr<Expression> Rehydrator::expression() {
454 int kind = this->readU8();
455 switch (kind) {
456 case Rehydrator::kBinary_Command: {
457 std::unique_ptr<Expression> left = this->expression();
458 Token::Kind op = (Token::Kind) this->readU8();
459 std::unique_ptr<Expression> right = this->expression();
460 const Type* type = this->type();
461 return std::unique_ptr<Expression>(new BinaryExpression(-1, std::move(left), op,
462 std::move(right), *type));
463 }
464 case Rehydrator::kBoolLiteral_Command: {
465 bool value = this->readU8();
466 return std::unique_ptr<Expression>(new BoolLiteral(fContext, -1, value));
467 }
468 case Rehydrator::kConstructor_Command: {
469 const Type* type = this->type();
470 uint8_t argCount = this->readU8();
471 std::vector<std::unique_ptr<Expression>> args;
472 args.reserve(argCount);
473 for (int i = 0; i < argCount; ++i) {
474 args.push_back(this->expression());
475 }
476 return std::unique_ptr<Expression>(new Constructor(-1, *type, std::move(args)));
477 }
478 case Rehydrator::kFieldAccess_Command: {
479 std::unique_ptr<Expression> base = this->expression();
480 int index = this->readU8();
481 FieldAccess::OwnerKind ownerKind = (FieldAccess::OwnerKind) this->readU8();
482 return std::unique_ptr<Expression>(new FieldAccess(std::move(base), index, ownerKind));
483 }
484 case Rehydrator::kFloatLiteral_Command: {
485 FloatIntUnion u;
486 u.fInt = this->readS32();
487 return std::unique_ptr<Expression>(new FloatLiteral(fContext, -1, u.fFloat));
488 }
489 case Rehydrator::kFunctionCall_Command: {
490 const Type* type = this->type();
491 const FunctionDeclaration* f = this->symbolRef<FunctionDeclaration>(
492 Symbol::kFunctionDeclaration_Kind);
493 uint8_t argCount = this->readU8();
494 std::vector<std::unique_ptr<Expression>> args;
495 args.reserve(argCount);
496 for (int i = 0; i < argCount; ++i) {
497 args.push_back(this->expression());
498 }
499 return std::unique_ptr<Expression>(new FunctionCall(-1, *type, *f, std::move(args)));
500 }
501 case Rehydrator::kIndex_Command: {
502 std::unique_ptr<Expression> base = this->expression();
503 std::unique_ptr<Expression> index = this->expression();
504 return std::unique_ptr<Expression>(new IndexExpression(fContext, std::move(base),
505 std::move(index)));
506 }
507 case Rehydrator::kIntLiteral_Command: {
508 int value = this->readS32();
509 return std::unique_ptr<Expression>(new IntLiteral(fContext, -1, value));
510 }
511 case Rehydrator::kNullLiteral_Command:
512 return std::unique_ptr<Expression>(new NullLiteral(fContext, -1));
513 case Rehydrator::kPostfix_Command: {
514 Token::Kind op = (Token::Kind) this->readU8();
515 std::unique_ptr<Expression> operand = this->expression();
516 return std::unique_ptr<Expression>(new PostfixExpression(std::move(operand), op));
517 }
518 case Rehydrator::kPrefix_Command: {
519 Token::Kind op = (Token::Kind) this->readU8();
520 std::unique_ptr<Expression> operand = this->expression();
521 return std::unique_ptr<Expression>(new PrefixExpression(op, std::move(operand)));
522 }
523 case Rehydrator::kSetting_Command: {
524 StringFragment name = this->readString();
525 std::unique_ptr<Expression> value = this->expression();
526 return std::unique_ptr<Expression>(new Setting(-1, name, std::move(value)));
527 }
528 case Rehydrator::kSwizzle_Command: {
529 std::unique_ptr<Expression> base = this->expression();
530 int count = this->readU8();
531 std::vector<int> components;
532 components.reserve(count);
533 for (int i = 0; i < count; ++i) {
534 components.push_back(this->readU8());
535 }
536 return std::unique_ptr<Expression>(new Swizzle(fContext, std::move(base),
537 std::move(components)));
538 }
539 case Rehydrator::kTernary_Command: {
540 std::unique_ptr<Expression> test = this->expression();
541 std::unique_ptr<Expression> ifTrue = this->expression();
542 std::unique_ptr<Expression> ifFalse = this->expression();
543 return std::unique_ptr<Expression>(new TernaryExpression(-1, std::move(test),
544 std::move(ifFalse),
545 std::move(ifTrue)));
546 }
547 case Rehydrator::kVariableReference_Command: {
548 const Variable* var = this->symbolRef<Variable>(Symbol::kVariable_Kind);
549 VariableReference::RefKind refKind = (VariableReference::RefKind) this->readU8();
550 return std::unique_ptr<Expression>(new VariableReference(-1, *var, refKind));
551 }
552 case Rehydrator::kVoid_Command:
553 return nullptr;
554 default:
555 printf("unsupported expression %d\n", kind);
556 SkASSERT(false);
557 return nullptr;
558 }
559}
560
561std::shared_ptr<SymbolTable> Rehydrator::symbolTable() {
562 int command = this->readU8();
563 if (command == kVoid_Command) {
564 return nullptr;
565 }
566 SkASSERT(command == kSymbolTable_Command);
567 uint16_t ownedCount = this->readU16();
568 std::shared_ptr<SymbolTable> result(new SymbolTable(fSymbolTable));
569 fSymbolTable = result;
570 std::vector<const Symbol*> ownedSymbols;
571 ownedSymbols.reserve(ownedCount);
572 for (int i = 0; i < ownedCount; ++i) {
573 ownedSymbols.push_back(this->symbol());
574 }
575 uint16_t symbolCount = this->readU16();
576 std::vector<std::pair<StringFragment, int>> symbols;
577 symbols.reserve(symbolCount);
578 for (int i = 0; i < symbolCount; ++i) {
579 StringFragment name = this->readString();
580 int index = this->readU16();
581 fSymbolTable->addWithoutOwnership(name, ownedSymbols[index]);
582 }
583 fSymbolTable = fSymbolTable->fParent;
584 return result;
585}
586
John Stilesa6841be2020-08-06 14:11:56 -0400587} // namespace SkSL