SkScript2.h revision 8a1c16ff38322f0210116fa7293eb8817c7e477e
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
11typedef SkLongArray(SkString*) SkTDStringArray;
12
13class SkAnimateMaker;
14class SkScriptCallBack;
15
16class SkScriptEngine2 {
17public:
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);
37	Error getError() { return fError; }
38	SkOperand2::OpType getReturnType() { return fReturnType; }
39	void track(SkOpArray* array) {
40		SkASSERT(fTrackArray.find(array) < 0);
41		*fTrackArray.append() = array; }
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
155protected:
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 {
181		Branch() {
182		}
183
184		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
203		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);
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;
262private:
263#ifdef SK_DEBUG
264public:
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
273struct 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