blob: 4d8bd8c0e5b57f9ba2a8ce3ca7c41089a27ee2aa [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001#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