Home | History | Annotate | Download | only in animator
      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);
     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;
     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 {
    188 		Branch() {
    189 		}
    190 
    191 		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
    210 		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);
    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