|
1 |
|
2 /* |
|
3 * Copyright 2011 Google Inc. |
|
4 * |
|
5 * Use of this source code is governed by a BSD-style license that can be |
|
6 * found in the LICENSE file. |
|
7 */ |
|
8 #ifndef SkScript2_DEFINED |
|
9 #define SkScript2_DEFINED |
|
10 |
|
11 #include "SkOperand2.h" |
|
12 #include "SkStream.h" |
|
13 #include "SkTDArray.h" |
|
14 #include "SkTDArray_Experimental.h" |
|
15 #include "SkTDict.h" |
|
16 #include "SkTDStack.h" |
|
17 |
|
18 typedef SkLongArray(SkString*) SkTDStringArray; |
|
19 |
|
20 class SkAnimateMaker; |
|
21 class SkScriptCallBack; |
|
22 |
|
23 class SkScriptEngine2 { |
|
24 public: |
|
25 enum Error { |
|
26 kNoError, |
|
27 kArrayIndexOutOfBounds, |
|
28 kCouldNotFindReferencedID, |
|
29 kFunctionCallFailed, |
|
30 kMemberOpFailed, |
|
31 kPropertyOpFailed |
|
32 }; |
|
33 |
|
34 enum Attrs { |
|
35 kConstant, |
|
36 kVariable |
|
37 }; |
|
38 |
|
39 SkScriptEngine2(SkOperand2::OpType returnType); |
|
40 ~SkScriptEngine2(); |
|
41 bool convertTo(SkOperand2::OpType , SkScriptValue2* ); |
|
42 bool evaluateScript(const char** script, SkScriptValue2* value); |
|
43 void forget(SkOpArray* array); |
|
44 Error getError() { return fError; } |
|
45 SkOperand2::OpType getReturnType() { return fReturnType; } |
|
46 void track(SkOpArray* array) { |
|
47 SkASSERT(fTrackArray.find(array) < 0); |
|
48 *fTrackArray.append() = array; } |
|
49 void track(SkString* string) { |
|
50 SkASSERT(fTrackString.find(string) < 0); |
|
51 *fTrackString.append() = string; |
|
52 } |
|
53 static bool ConvertTo(SkScriptEngine2* , SkOperand2::OpType toType, SkScriptValue2* value); |
|
54 static SkScalar IntToScalar(int32_t ); |
|
55 static bool ValueToString(const SkScriptValue2& value, SkString* string); |
|
56 |
|
57 enum Op { // used by tokenizer attribute table |
|
58 kUnassigned, |
|
59 kAdd, |
|
60 kBitAnd, |
|
61 kBitNot, |
|
62 kBitOr, |
|
63 kDivide, |
|
64 kEqual, |
|
65 kFlipOps, |
|
66 kGreaterEqual, |
|
67 kLogicalAnd, |
|
68 kLogicalNot, |
|
69 kLogicalOr, |
|
70 kMinus, |
|
71 kModulo, |
|
72 kMultiply, |
|
73 kShiftLeft, |
|
74 kShiftRight, // signed |
|
75 kSubtract, |
|
76 kXor, |
|
77 // following not in attribute table |
|
78 kArrayOp, |
|
79 kElse, |
|
80 kIf, |
|
81 kParen, |
|
82 kLastLogicalOp, |
|
83 kArtificialOp = 0x20 |
|
84 }; |
|
85 |
|
86 enum TypeOp { // generated by tokenizer |
|
87 kNop, // should never get generated |
|
88 kAccumulatorPop, |
|
89 kAccumulatorPush, |
|
90 kAddInt, |
|
91 kAddScalar, |
|
92 kAddString, // string concat |
|
93 kArrayIndex, |
|
94 kArrayParam, |
|
95 kArrayToken, |
|
96 kBitAndInt, |
|
97 kBitNotInt, |
|
98 kBitOrInt, |
|
99 kBoxToken, |
|
100 kCallback, |
|
101 kDivideInt, |
|
102 kDivideScalar, |
|
103 kDotOperator, |
|
104 kElseOp, |
|
105 kEnd, |
|
106 kEqualInt, |
|
107 kEqualScalar, |
|
108 kEqualString, |
|
109 kFunctionCall, |
|
110 kFlipOpsOp, |
|
111 kFunctionToken, |
|
112 kGreaterEqualInt, |
|
113 kGreaterEqualScalar, |
|
114 kGreaterEqualString, |
|
115 kIfOp, |
|
116 kIntToScalar, |
|
117 kIntToScalar2, |
|
118 kIntToString, |
|
119 kIntToString2, |
|
120 kIntegerAccumulator, |
|
121 kIntegerOperand, |
|
122 kLogicalAndInt, |
|
123 kLogicalNotInt, |
|
124 kLogicalOrInt, |
|
125 kMemberOp, |
|
126 kMinusInt, |
|
127 kMinusScalar, |
|
128 kModuloInt, |
|
129 kModuloScalar, |
|
130 kMultiplyInt, |
|
131 kMultiplyScalar, |
|
132 kPropertyOp, |
|
133 kScalarAccumulator, |
|
134 kScalarOperand, |
|
135 kScalarToInt, |
|
136 kScalarToInt2, |
|
137 kScalarToString, |
|
138 kScalarToString2, |
|
139 kShiftLeftInt, |
|
140 kShiftRightInt, // signed |
|
141 kStringAccumulator, |
|
142 kStringOperand, |
|
143 kStringToInt, |
|
144 kStringToScalar, |
|
145 kStringToScalar2, |
|
146 kStringTrack, |
|
147 kSubtractInt, |
|
148 kSubtractScalar, |
|
149 kToBool, |
|
150 kUnboxToken, |
|
151 kUnboxToken2, |
|
152 kXorInt, |
|
153 kLastTypeOp |
|
154 }; |
|
155 |
|
156 enum OpBias { |
|
157 kNoBias, |
|
158 kTowardsNumber = 0, |
|
159 kTowardsString |
|
160 }; |
|
161 |
|
162 protected: |
|
163 |
|
164 enum BraceStyle { |
|
165 // kStructBrace, |
|
166 kArrayBrace, |
|
167 kFunctionBrace |
|
168 }; |
|
169 |
|
170 enum AddTokenRegister { |
|
171 kAccumulator, |
|
172 kOperand |
|
173 }; |
|
174 |
|
175 enum ResultIsBoolean { |
|
176 kResultIsNotBoolean, |
|
177 kResultIsBoolean |
|
178 }; |
|
179 |
|
180 struct OperatorAttributes { |
|
181 unsigned int fLeftType : 3; // SkOpType union, but only lower values |
|
182 unsigned int fRightType : 3; // SkOpType union, but only lower values |
|
183 OpBias fBias : 1; |
|
184 ResultIsBoolean fResultIsBoolean : 1; |
|
185 }; |
|
186 |
|
187 struct Branch { |
|
188 Branch() { |
|
189 } |
|
190 |
|
191 Branch(Op op, int depth, unsigned offset) : fOffset(offset), fOpStackDepth(depth), fOperator(op), |
|
192 fPrimed(kIsNotPrimed), fDone(kIsNotDone) { |
|
193 } |
|
194 |
|
195 enum Primed { |
|
196 kIsNotPrimed, |
|
197 kIsPrimed |
|
198 }; |
|
199 |
|
200 enum Done { |
|
201 kIsNotDone, |
|
202 kIsDone, |
|
203 }; |
|
204 |
|
205 unsigned fOffset : 16; // offset in generated stream where branch needs to go |
|
206 int fOpStackDepth : 7; // depth when operator was found |
|
207 Op fOperator : 6; // operand which generated branch |
|
208 mutable Primed fPrimed : 1; // mark when next instruction generates branch |
|
209 Done fDone : 1; // mark when branch is complete |
|
210 void prime() { fPrimed = kIsPrimed; } |
|
211 void resolve(SkDynamicMemoryWStream* , size_t offset); |
|
212 }; |
|
213 |
|
214 static const OperatorAttributes gOpAttributes[]; |
|
215 static const signed char gPrecedence[]; |
|
216 static const TypeOp gTokens[]; |
|
217 void addToken(TypeOp ); |
|
218 void addTokenConst(SkScriptValue2* , AddTokenRegister , SkOperand2::OpType , TypeOp ); |
|
219 void addTokenInt(int ); |
|
220 void addTokenScalar(SkScalar ); |
|
221 void addTokenString(const SkString& ); |
|
222 void addTokenValue(const SkScriptValue2& , AddTokenRegister ); |
|
223 int arithmeticOp(char ch, char nextChar, bool lastPush); |
|
224 bool convertParams(SkTDArray<SkScriptValue2>* , |
|
225 const SkOperand2::OpType* paramTypes, int paramTypeCount); |
|
226 void convertToString(SkOperand2* operand, SkOperand2::OpType type) { |
|
227 SkScriptValue2 scriptValue; |
|
228 scriptValue.fOperand = *operand; |
|
229 scriptValue.fType = type; |
|
230 convertTo(SkOperand2::kString, &scriptValue); |
|
231 *operand = scriptValue.fOperand; |
|
232 } |
|
233 bool evaluateDot(const char*& script); |
|
234 bool evaluateDotParam(const char*& script, const char* field, size_t fieldLength); |
|
235 bool functionParams(const char** scriptPtr, SkTDArray<SkScriptValue2>* params); |
|
236 size_t getTokenOffset(); |
|
237 SkOperand2::OpType getUnboxType(SkOperand2 scriptValue); |
|
238 bool handleArrayIndexer(const char** scriptPtr); |
|
239 bool handleFunction(const char** scriptPtr); |
|
240 bool handleMember(const char* field, size_t len, void* object); |
|
241 bool handleMemberFunction(const char* field, size_t len, void* object, |
|
242 SkTDArray<SkScriptValue2>* params); |
|
243 bool handleProperty(); |
|
244 bool handleUnbox(SkScriptValue2* scriptValue); |
|
245 bool innerScript(const char** scriptPtr, SkScriptValue2* value); |
|
246 int logicalOp(char ch, char nextChar); |
|
247 void processLogicalOp(Op op); |
|
248 bool processOp(); |
|
249 void resolveBranch(Branch& ); |
|
250 // void setAnimateMaker(SkAnimateMaker* maker) { fMaker = maker; } |
|
251 SkDynamicMemoryWStream fStream; |
|
252 SkDynamicMemoryWStream* fActiveStream; |
|
253 SkTDStack<BraceStyle> fBraceStack; // curly, square, function paren |
|
254 SkTDStack<Branch> fBranchStack; // logical operators, slot to store forward branch |
|
255 SkLongArray(SkScriptCallBack*) fCallBackArray; |
|
256 SkTDStack<Op> fOpStack; |
|
257 SkTDStack<SkScriptValue2> fValueStack; |
|
258 // SkAnimateMaker* fMaker; |
|
259 SkLongArray(SkOpArray*) fTrackArray; |
|
260 SkTDStringArray fTrackString; |
|
261 const char* fToken; // one-deep stack |
|
262 size_t fTokenLength; |
|
263 SkOperand2::OpType fReturnType; |
|
264 Error fError; |
|
265 SkOperand2::OpType fAccumulatorType; // tracking for code generation |
|
266 SkBool fBranchPopAllowed; |
|
267 SkBool fConstExpression; |
|
268 SkBool fOperandInUse; |
|
269 private: |
|
270 #ifdef SK_DEBUG |
|
271 public: |
|
272 void decompile(const unsigned char* , size_t ); |
|
273 static void UnitTest(); |
|
274 static void ValidateDecompileTable(); |
|
275 #endif |
|
276 }; |
|
277 |
|
278 #ifdef SK_DEBUG |
|
279 |
|
280 struct SkScriptNAnswer2 { |
|
281 const char* fScript; |
|
282 SkOperand2::OpType fType; |
|
283 int32_t fIntAnswer; |
|
284 SkScalar fScalarAnswer; |
|
285 const char* fStringAnswer; |
|
286 }; |
|
287 |
|
288 #endif |
|
289 |
|
290 |
|
291 #endif // SkScript2_DEFINED |