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