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