• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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);
getError()44 	Error getError() { return fError; }
getReturnType()45 	SkOperand2::OpType getReturnType() { return fReturnType; }
track(SkOpArray * array)46 	void track(SkOpArray* array) {
47 		SkASSERT(fTrackArray.find(array) < 0);
48 		*fTrackArray.append() = array; }
track(SkString * string)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 {
BranchBranch188 		Branch() {
189 		}
190 
BranchBranch191 		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
primeBranch210 		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);
convertToString(SkOperand2 * operand,SkOperand2::OpType type)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
292 
293