Fix Rehydrator bug with built-in variable references.

We need to use `possiblyBuiltinSymbolRef` when rehydrating variable
references to account for dehydrated code which accesses variables like
sk_FragCoord.

Change-Id: I2ae596eb0c78b289b69fa1dd10bf01b83981a0f6
Bug: skia:13164
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/532237
Auto-Submit: John Stiles <johnstiles@google.com>
Reviewed-by: Ethan Nicholas <ethannicholas@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
John Stiles 2022-04-21 09:23:49 -04:00 committed by SkCQ
parent ccd85d5835
commit d67a67c4bd
3 changed files with 13 additions and 19 deletions

View File

@ -728,7 +728,6 @@ generated_cc_atom(
"//include/private:SkSLDefines_hdr",
"//include/private:SkSLLayout_hdr",
"//include/private:SkSLModifiers_hdr",
"//include/private:SkSLSymbol_hdr",
"//src/sksl/ir:SkSLSymbolTable_hdr",
],
)
@ -750,6 +749,7 @@ generated_cc_atom(
"//include/private:SkSLProgramElement_hdr",
"//include/private:SkSLProgramKind_hdr",
"//include/private:SkSLStatement_hdr",
"//include/private:SkSLSymbol_hdr",
"//include/private:SkTArray_hdr",
"//include/sksl:DSLCore_hdr",
"//include/sksl:SkSLOperator_hdr",

View File

@ -11,6 +11,7 @@
#include "include/private/SkSLProgramElement.h"
#include "include/private/SkSLProgramKind.h"
#include "include/private/SkSLStatement.h"
#include "include/private/SkSLSymbol.h"
#include "include/private/SkTArray.h"
#include "include/sksl/DSLCore.h"
#include "include/sksl/SkSLOperator.h"
@ -193,7 +194,7 @@ const Symbol* Rehydrator::symbol() {
std::vector<const Variable*> parameters;
parameters.reserve(parameterCount);
for (int i = 0; i < parameterCount; ++i) {
parameters.push_back(this->symbolRef<Variable>(Symbol::Kind::kVariable));
parameters.push_back(this->symbolRef<Variable>());
}
const Type* returnType = this->type();
const FunctionDeclaration* result =
@ -208,7 +209,7 @@ const Symbol* Rehydrator::symbol() {
return result;
}
case kField_Command: {
const Variable* owner = this->symbolRef<Variable>(Symbol::Kind::kVariable);
const Variable* owner = this->symbolRef<Variable>();
uint8_t index = this->readU8();
const Field* result = fSymbolTable->takeOwnershipOfSymbol(
std::make_unique<Field>(Position(), owner, index));
@ -234,12 +235,7 @@ const Symbol* Rehydrator::symbol() {
return result;
}
case kSymbolRef_Command: {
uint16_t id = this->readU16();
if (id == kBuiltin_Symbol) {
return (*fSymbolTable)[this->readString()];
}
SkASSERT(fSymbols.size() > id);
return fSymbols[id];
return this->possiblyBuiltinSymbolRef();
}
case kUnresolvedFunction_Command: {
uint16_t id = this->readU16();
@ -331,8 +327,7 @@ std::unique_ptr<ProgramElement> Rehydrator::element() {
int kind = this->readU8();
switch (kind) {
case Rehydrator::kFunctionDefinition_Command: {
const FunctionDeclaration* decl = this->symbolRef<FunctionDeclaration>(
Symbol::Kind::kFunctionDeclaration);
const FunctionDeclaration* decl = this->symbolRef<FunctionDeclaration>();
std::unique_ptr<Statement> body = this->statement();
auto result = FunctionDefinition::Convert(this->context(), Position(), *decl,
std::move(body), fSymbolTable->isBuiltin());
@ -340,8 +335,7 @@ std::unique_ptr<ProgramElement> Rehydrator::element() {
return std::move(result);
}
case Rehydrator::kFunctionPrototype_Command: {
const FunctionDeclaration* decl = this->symbolRef<FunctionDeclaration>(
Symbol::Kind::kFunctionDeclaration);
const FunctionDeclaration* decl = this->symbolRef<FunctionDeclaration>();
// since we skip over builtin prototypes when dehydrating, we know that this
// builtin=false
return std::make_unique<FunctionPrototype>(Position(), decl, /*builtin=*/false);
@ -435,8 +429,7 @@ std::unique_ptr<Statement> Rehydrator::statement() {
std::move(ifTrue), std::move(ifFalse));
}
case Rehydrator::kInlineMarker_Command: {
const FunctionDeclaration* funcDecl = this->symbolRef<FunctionDeclaration>(
Symbol::Kind::kFunctionDeclaration);
const FunctionDeclaration* funcDecl = this->symbolRef<FunctionDeclaration>();
return InlineMarker::Make(funcDecl);
}
case Rehydrator::kNop_Command:
@ -468,7 +461,7 @@ std::unique_ptr<Statement> Rehydrator::statement() {
std::move(cases), fSymbolTable);
}
case Rehydrator::kVarDeclaration_Command: {
Variable* var = this->symbolRef<Variable>(Symbol::Kind::kVariable);
Variable* var = this->symbolRef<Variable>();
const Type* baseType = this->type();
int arraySize = this->readU8();
std::unique_ptr<Expression> value = this->expression();
@ -634,7 +627,7 @@ std::unique_ptr<Expression> Rehydrator::expression() {
std::move(ifTrue), std::move(ifFalse));
}
case Rehydrator::kVariableReference_Command: {
const Variable* var = this->symbolRef<Variable>(Symbol::Kind::kVariable);
const Variable* var = &this->possiblyBuiltinSymbolRef()->as<Variable>();
VariableReference::RefKind refKind = (VariableReference::RefKind) this->readU8();
return VariableReference::Make(pos, var, refKind);
}

View File

@ -12,7 +12,6 @@
#include "include/private/SkSLDefines.h"
#include "include/private/SkSLLayout.h"
#include "include/private/SkSLModifiers.h"
#include "include/private/SkSLSymbol.h"
#include "src/sksl/SkSLContext.h"
#include "src/sksl/ir/SkSLSymbolTable.h"
@ -28,6 +27,7 @@ class Expression;
class ModifiersPool;
class ProgramElement;
class Statement;
class Symbol;
class Type;
struct Program;
@ -174,8 +174,9 @@ private:
}
template<typename T>
T* symbolRef(Symbol::Kind kind) {
T* symbolRef() {
uint16_t result = this->readU16();
SkASSERTF(result != kBuiltin_Symbol, "use possiblyBuiltinSymbolRef() instead");
SkASSERT(fSymbols.size() > result);
return (T*) fSymbols[result];
}