3 * Copyright 2011 Google Inc.
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
8 #ifndef SkScript2_DEFINED
9 #define SkScript2_DEFINED
11 #include "SkOperand2.h"
13 #include "SkTDArray.h"
14 #include "SkTDArray_Experimental.h"
16 #include "SkTDStack.h"
18 typedef SkLongArray(SkString*) SkTDStringArray;
21 class SkScriptCallBack;
23 class SkScriptEngine2 {
27 kArrayIndexOutOfBounds,
28 kCouldNotFindReferencedID,
39 SkScriptEngine2(SkOperand2::OpType returnType);
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;
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);
57 enum Op { // used by tokenizer attribute table
74 kShiftRight, // signed
77 // following not in attribute table
86 enum TypeOp { // generated by tokenizer
87 kNop, // should never get generated
92 kAddString, // string concat
140 kShiftRightInt, // signed
170 enum AddTokenRegister {
175 enum ResultIsBoolean {
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
184 ResultIsBoolean fResultIsBoolean : 1;
191 Branch(Op op, int depth, size_t offset)
192 : fOffset(SkToU16(offset)), fOpStackDepth(depth), fOperator(op)
193 , fPrimed(kIsNotPrimed), fDone(kIsNotDone) {
206 unsigned fOffset : 16; // offset in generated stream where branch needs to go
207 int fOpStackDepth : 7; // depth when operator was found
208 Op fOperator : 6; // operand which generated branch
209 mutable Primed fPrimed : 1; // mark when next instruction generates branch
210 Done fDone : 1; // mark when branch is complete
211 void prime() { fPrimed = kIsPrimed; }
212 void resolve(SkDynamicMemoryWStream* , size_t offset);
215 static const OperatorAttributes gOpAttributes[];
216 static const signed char gPrecedence[];
217 static const TypeOp gTokens[];
218 void addToken(TypeOp );
219 void addTokenConst(SkScriptValue2* , AddTokenRegister , SkOperand2::OpType , TypeOp );
220 void addTokenInt(int );
221 void addTokenScalar(SkScalar );
222 void addTokenString(const SkString& );
223 void addTokenValue(const SkScriptValue2& , AddTokenRegister );
224 int arithmeticOp(char ch, char nextChar, bool lastPush);
225 bool convertParams(SkTDArray<SkScriptValue2>* ,
226 const SkOperand2::OpType* paramTypes, int paramTypeCount);
227 void convertToString(SkOperand2* operand, SkOperand2::OpType type) {
228 SkScriptValue2 scriptValue;
229 scriptValue.fOperand = *operand;
230 scriptValue.fType = type;
231 convertTo(SkOperand2::kString, &scriptValue);
232 *operand = scriptValue.fOperand;
234 bool evaluateDot(const char*& script);
235 bool evaluateDotParam(const char*& script, const char* field, size_t fieldLength);
236 bool functionParams(const char** scriptPtr, SkTDArray<SkScriptValue2>* params);
237 size_t getTokenOffset();
238 SkOperand2::OpType getUnboxType(SkOperand2 scriptValue);
239 bool handleArrayIndexer(const char** scriptPtr);
240 bool handleFunction(const char** scriptPtr);
241 bool handleMember(const char* field, size_t len, void* object);
242 bool handleMemberFunction(const char* field, size_t len, void* object,
243 SkTDArray<SkScriptValue2>* params);
244 bool handleProperty();
245 bool handleUnbox(SkScriptValue2* scriptValue);
246 bool innerScript(const char** scriptPtr, SkScriptValue2* value);
247 int logicalOp(char ch, char nextChar);
248 void processLogicalOp(Op op);
250 void resolveBranch(Branch& );
251 // void setAnimateMaker(SkAnimateMaker* maker) { fMaker = maker; }
252 SkDynamicMemoryWStream fStream;
253 SkDynamicMemoryWStream* fActiveStream;
254 SkTDStack<BraceStyle> fBraceStack; // curly, square, function paren
255 SkTDStack<Branch> fBranchStack; // logical operators, slot to store forward branch
256 SkLongArray(SkScriptCallBack*) fCallBackArray;
257 SkTDStack<Op> fOpStack;
258 SkTDStack<SkScriptValue2> fValueStack;
259 // SkAnimateMaker* fMaker;
260 SkLongArray(SkOpArray*) fTrackArray;
261 SkTDStringArray fTrackString;
262 const char* fToken; // one-deep stack
264 SkOperand2::OpType fReturnType;
266 SkOperand2::OpType fAccumulatorType; // tracking for code generation
267 SkBool fBranchPopAllowed;
268 SkBool fConstExpression;
269 SkBool fOperandInUse;
273 void decompile(const unsigned char* , size_t );
274 static void UnitTest();
275 static void ValidateDecompileTable();
281 struct SkScriptNAnswer2 {
283 SkOperand2::OpType fType;
285 SkScalar fScalarAnswer;
286 const char* fStringAnswer;
292 #endif // SkScript2_DEFINED