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