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