1 /*
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 "include/sksl/DSLVar.h"
9
10 #include "include/core/SkTypes.h"
11 #include "include/private/SkSLDefines.h"
12 #include "include/private/SkSLStatement.h"
13 #include "include/private/SkSLSymbol.h"
14 #include "include/sksl/DSLModifiers.h"
15 #include "include/sksl/DSLType.h"
16 #include "include/sksl/SkSLOperator.h"
17 #include "src/sksl/SkSLThreadContext.h"
18 #include "src/sksl/ir/SkSLBinaryExpression.h"
19 #include "src/sksl/ir/SkSLExpression.h"
20 #include "src/sksl/ir/SkSLFieldAccess.h"
21 #include "src/sksl/ir/SkSLFunctionCall.h"
22 #include "src/sksl/ir/SkSLSymbolTable.h"
23 #include "src/sksl/ir/SkSLVariable.h"
24
25 #include <utility>
26
27 namespace SkSL {
28
29 namespace dsl {
30
31 /**
32 * DSLVarBase
33 */
34
DSLVarBase(VariableStorage storage,DSLType type,std::string_view name,DSLExpression initialValue,Position pos,Position namePos)35 DSLVarBase::DSLVarBase(VariableStorage storage, DSLType type, std::string_view name,
36 DSLExpression initialValue, Position pos, Position namePos)
37 : DSLVarBase(storage, DSLModifiers(), std::move(type), name, std::move(initialValue),
38 pos, namePos) {}
39
DSLVarBase(VariableStorage storage,const DSLModifiers & modifiers,DSLType type,std::string_view name,DSLExpression initialValue,Position pos,Position namePos)40 DSLVarBase::DSLVarBase(VariableStorage storage, const DSLModifiers& modifiers, DSLType type,
41 std::string_view name, DSLExpression initialValue, Position pos,
42 Position namePos)
43 : fModifiers(std::move(modifiers))
44 , fType(std::move(type))
45 , fNamePosition(namePos)
46 , fName(name)
47 , fInitialValue(std::move(initialValue))
48 , fPosition(pos)
49 , fStorage(storage) {}
50
swap(DSLVarBase & other)51 void DSLVarBase::swap(DSLVarBase& other) {
52 SkASSERT(this->storage() == other.storage());
53 std::swap(fModifiers, other.fModifiers);
54 std::swap(fType, other.fType);
55 std::swap(fDeclaration, other.fDeclaration);
56 std::swap(fVar, other.fVar);
57 std::swap(fNamePosition, other.fNamePosition);
58 std::swap(fName, other.fName);
59 std::swap(fInitialValue.fExpression, other.fInitialValue.fExpression);
60 std::swap(fInitialized, other.fInitialized);
61 std::swap(fPosition, other.fPosition);
62 }
63
operator [](DSLExpression && index)64 DSLExpression DSLVarBase::operator[](DSLExpression&& index) {
65 return DSLExpression(*this)[std::move(index)];
66 }
67
assignExpression(DSLExpression expr)68 DSLExpression DSLVarBase::assignExpression(DSLExpression expr) {
69 return DSLExpression(BinaryExpression::Convert(ThreadContext::Context(), Position(),
70 DSLExpression(*this, Position()).release(), SkSL::Operator::Kind::EQ,
71 expr.release()));
72 }
73
74 /**
75 * DSLVar
76 */
77
DSLVar()78 DSLVar::DSLVar() : DSLVarBase(SkSL::VariableStorage::kLocal) {}
79
DSLVar(DSLType type,std::string_view name,DSLExpression initialValue,Position pos,Position namePos)80 DSLVar::DSLVar(DSLType type, std::string_view name, DSLExpression initialValue,
81 Position pos, Position namePos)
82 : INHERITED(SkSL::VariableStorage::kLocal, type, name, std::move(initialValue),
83 pos, namePos) {}
84
DSLVar(const DSLModifiers & modifiers,DSLType type,std::string_view name,DSLExpression initialValue,Position pos,Position namePos)85 DSLVar::DSLVar(const DSLModifiers& modifiers, DSLType type, std::string_view name,
86 DSLExpression initialValue, Position pos, Position namePos)
87 : INHERITED(SkSL::VariableStorage::kLocal, modifiers, type, name, std::move(initialValue),
88 pos, namePos) {}
89
swap(DSLVar & other)90 void DSLVar::swap(DSLVar& other) {
91 INHERITED::swap(other);
92 }
93
94 /**
95 * DSLGlobalVar
96 */
97
DSLGlobalVar()98 DSLGlobalVar::DSLGlobalVar() : DSLVarBase(SkSL::VariableStorage::kGlobal) {}
99
DSLGlobalVar(DSLType type,std::string_view name,DSLExpression initialValue,Position pos,Position namePos)100 DSLGlobalVar::DSLGlobalVar(DSLType type, std::string_view name, DSLExpression initialValue,
101 Position pos, Position namePos)
102 : INHERITED(SkSL::VariableStorage::kGlobal, type, name, std::move(initialValue),
103 pos, namePos) {}
104
DSLGlobalVar(const DSLModifiers & modifiers,DSLType type,std::string_view name,DSLExpression initialValue,Position pos,Position namePos)105 DSLGlobalVar::DSLGlobalVar(const DSLModifiers& modifiers, DSLType type, std::string_view name,
106 DSLExpression initialValue, Position pos, Position namePos)
107 : INHERITED(SkSL::VariableStorage::kGlobal, modifiers, type, name, std::move(initialValue),
108 pos, namePos) {}
109
DSLGlobalVar(const char * name)110 DSLGlobalVar::DSLGlobalVar(const char* name)
111 : INHERITED(SkSL::VariableStorage::kGlobal, kVoid_Type, name, DSLExpression(),
112 Position(), Position()) {
113 fName = name;
114 SkSL::SymbolTable* symbolTable = ThreadContext::SymbolTable().get();
115 SkSL::Symbol* result = symbolTable->findMutable(fName);
116 SkASSERTF(result, "could not find '%.*s' in symbol table", (int)fName.length(), fName.data());
117 fVar = &result->as<SkSL::Variable>();
118 fInitialized = true;
119 }
120
swap(DSLGlobalVar & other)121 void DSLGlobalVar::swap(DSLGlobalVar& other) {
122 INHERITED::swap(other);
123 }
124
methodCall(std::string_view methodName,Position pos)125 std::unique_ptr<SkSL::Expression> DSLGlobalVar::methodCall(std::string_view methodName,
126 Position pos) {
127 if (!this->fType.isEffectChild()) {
128 ThreadContext::ReportError("type does not support method calls", pos);
129 return nullptr;
130 }
131 return FieldAccess::Convert(ThreadContext::Context(), pos, *ThreadContext::SymbolTable(),
132 DSLExpression(*this, pos).release(), methodName);
133 }
134
eval(ExpressionArray args,Position pos)135 DSLExpression DSLGlobalVar::eval(ExpressionArray args, Position pos) {
136 auto method = this->methodCall("eval", pos);
137 return DSLExpression(
138 method ? SkSL::FunctionCall::Convert(ThreadContext::Context(), pos, std::move(method),
139 std::move(args))
140 : nullptr,
141 pos);
142 }
143
eval(DSLExpression x,Position pos)144 DSLExpression DSLGlobalVar::eval(DSLExpression x, Position pos) {
145 ExpressionArray converted;
146 converted.push_back(x.release());
147 return this->eval(std::move(converted), pos);
148 }
149
eval(DSLExpression x,DSLExpression y,Position pos)150 DSLExpression DSLGlobalVar::eval(DSLExpression x, DSLExpression y, Position pos) {
151 ExpressionArray converted;
152 converted.push_back(x.release());
153 converted.push_back(y.release());
154 return this->eval(std::move(converted), pos);
155 }
156
157 /**
158 * DSLParameter
159 */
160
DSLParameter()161 DSLParameter::DSLParameter() : DSLVarBase(SkSL::VariableStorage::kParameter) {}
162
DSLParameter(DSLType type,std::string_view name,Position pos,Position namePos)163 DSLParameter::DSLParameter(DSLType type, std::string_view name, Position pos, Position namePos)
164 : INHERITED(SkSL::VariableStorage::kParameter, type, name, DSLExpression(), pos, namePos) {}
165
DSLParameter(const DSLModifiers & modifiers,DSLType type,std::string_view name,Position pos,Position namePos)166 DSLParameter::DSLParameter(const DSLModifiers& modifiers, DSLType type, std::string_view name,
167 Position pos, Position namePos)
168 : INHERITED(SkSL::VariableStorage::kParameter, modifiers, type, name, DSLExpression(),
169 pos, namePos) {}
170
swap(DSLParameter & other)171 void DSLParameter::swap(DSLParameter& other) {
172 INHERITED::swap(other);
173 }
174
175 } // namespace dsl
176
177 } // namespace SkSL
178