1 2 /* 3 * Copyright 2006 The Android Open Source Project 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 9 10 #ifndef SkScript_DEFINED 11 #define SkScript_DEFINED 12 13 #include "SkOperand.h" 14 #include "SkIntArray.h" 15 #include "SkTDict.h" 16 #include "SkTDStack.h" 17 18 class SkAnimateMaker; 19 20 class SkScriptEngine { 21 public: 22 enum Error { 23 kNoError, 24 kArrayIndexOutOfBounds, 25 kCouldNotFindReferencedID, 26 kDotOperatorExpectsObject, 27 kErrorInArrrayIndex, 28 kErrorInFunctionParameters, 29 kExpectedArray, 30 kExpectedBooleanExpression, 31 kExpectedFieldName, 32 kExpectedHex, 33 kExpectedIntForConditionOperator, 34 kExpectedNumber, 35 kExpectedNumberForArrayIndex, 36 kExpectedOperator, 37 kExpectedToken, 38 kExpectedTokenBeforeDotOperator, 39 kExpectedValue, 40 kHandleMemberFailed, 41 kHandleMemberFunctionFailed, 42 kHandleUnboxFailed, 43 kIndexOutOfRange, 44 kMismatchedArrayBrace, 45 kMismatchedBrackets, 46 kNoFunctionHandlerFound, 47 kPrematureEnd, 48 kTooManyParameters, 49 kTypeConversionFailed, 50 kUnterminatedString 51 }; 52 53 enum SkOpType { 54 kNoType, 55 kInt = 1, 56 kScalar = 2, 57 kString = 4, 58 kArray = 8, 59 kObject = 16 60 // kStruct = 32 61 }; 62 63 typedef bool (*_boxCallBack)(void* userStorage, SkScriptValue* result); 64 typedef bool (*_functionCallBack)(const char* func, size_t len, SkTDArray<SkScriptValue>& params, 65 void* userStorage, SkScriptValue* result); 66 typedef bool (*_memberCallBack)(const char* member, size_t len, void* object, 67 void* userStorage, SkScriptValue* result); 68 typedef bool (*_memberFunctionCallBack)(const char* member, size_t len, void* object, 69 SkTDArray<SkScriptValue>& params, void* userStorage, SkScriptValue* result); 70 // typedef bool (*_objectToStringCallBack)(void* object, void* userStorage, SkScriptValue* result); 71 typedef bool (*_propertyCallBack)(const char* prop, size_t len, void* userStorage, SkScriptValue* result); 72 typedef bool (*_unboxCallBack)(void* userStorage, SkScriptValue* result); 73 SkScriptEngine(SkOpType returnType); 74 ~SkScriptEngine(); 75 void boxCallBack(_boxCallBack func, void* userStorage); 76 bool convertTo(SkDisplayTypes , SkScriptValue* ); 77 bool evaluateScript(const char** script, SkScriptValue* value); 78 void forget(SkTypedArray* array); 79 void functionCallBack(_functionCallBack func, void* userStorage); getError()80 Error getError() const { return fError; } 81 #ifdef SK_DEBUG 82 bool getErrorString(SkString* err) const; 83 #endif 84 void memberCallBack(_memberCallBack , void* userStorage); 85 void memberFunctionCallBack(_memberFunctionCallBack , void* userStorage); 86 // void objectToStringCallBack(_objectToStringCallBack , void* userStorage); 87 void propertyCallBack(_propertyCallBack prop, void* userStorage); 88 void track(SkTypedArray* array); 89 void track(SkString* string); 90 void unboxCallBack(_unboxCallBack func, void* userStorage); 91 static bool ConvertTo(SkScriptEngine* , SkDisplayTypes toType, SkScriptValue* value); 92 static SkScalar IntToScalar(int32_t ); 93 static SkDisplayTypes ToDisplayType(SkOpType type); 94 static SkOpType ToOpType(SkDisplayTypes type); 95 static bool ValueToString(SkScriptValue value, SkString* string); 96 97 enum CallBackType { 98 kBox, 99 kFunction, 100 kMember, 101 kMemberFunction, 102 // kObjectToString, 103 kProperty, 104 kUnbox 105 }; 106 107 struct UserCallBack { 108 CallBackType fCallBackType; 109 void* fUserStorage; 110 union { 111 _boxCallBack fBoxCallBack; 112 _functionCallBack fFunctionCallBack; 113 _memberCallBack fMemberCallBack; 114 _memberFunctionCallBack fMemberFunctionCallBack; 115 // _objectToStringCallBack fObjectToStringCallBack; 116 _propertyCallBack fPropertyCallBack; 117 _unboxCallBack fUnboxCallBack; 118 }; 119 }; 120 121 enum SkOp { 122 kUnassigned, 123 kAdd, 124 kAddInt = kAdd, 125 kAddScalar, 126 kAddString, // string concat 127 kArrayOp, 128 kBitAnd, 129 kBitNot, 130 kBitOr, 131 kDivide, 132 kDivideInt = kDivide, 133 kDivideScalar, 134 kElse, 135 kEqual, 136 kEqualInt = kEqual, 137 kEqualScalar, 138 kEqualString, 139 kFlipOps, 140 kGreaterEqual, 141 kGreaterEqualInt = kGreaterEqual, 142 kGreaterEqualScalar, 143 kGreaterEqualString, 144 kIf, 145 kLogicalAnd, 146 kLogicalNot, 147 kLogicalOr, 148 kMinus, 149 kMinusInt = kMinus, 150 kMinusScalar, 151 kModulo, 152 kModuloInt = kModulo, 153 kModuloScalar, 154 kMultiply, 155 kMultiplyInt = kMultiply, 156 kMultiplyScalar, 157 kParen, 158 kShiftLeft, 159 kShiftRight, // signed 160 kSubtract, 161 kSubtractInt = kSubtract, 162 kSubtractScalar, 163 kXor, 164 kArtificialOp = 0x40 165 }; 166 167 enum SkOpBias { 168 kNoBias, 169 kTowardsNumber = 0, 170 kTowardsString 171 }; 172 173 protected: 174 175 struct SkOperatorAttributes { 176 unsigned int fLeftType : 3; // SkOpType, but only lower values 177 unsigned int fRightType : 3; // SkOpType, but only lower values 178 SkOpBias fBias : 1; 179 }; 180 181 struct SkSuppress { // !!! could be compressed to a long 182 SkOp fOperator; // operand which enabled suppression 183 int fOpStackDepth; // depth when suppression operator was found 184 SkBool8 fSuppress; // set if suppression happens now, as opposed to later 185 SkBool8 fElse; // set on the : half of ? : 186 }; 187 188 static const SkOperatorAttributes gOpAttributes[]; 189 static const signed char gPrecedence[]; 190 int arithmeticOp(char ch, char nextChar, bool lastPush); 191 void commonCallBack(CallBackType type, UserCallBack& callBack, void* userStorage); 192 bool convertParams(SkTDArray<SkScriptValue>&, const SkFunctionParamType* , 193 int paramTypeCount); convertToString(SkOperand & operand,SkDisplayTypes type)194 void convertToString(SkOperand& operand, SkDisplayTypes type) { 195 SkScriptValue scriptValue; 196 scriptValue.fOperand = operand; 197 scriptValue.fType = type; 198 convertTo(SkType_String, &scriptValue); 199 operand = scriptValue.fOperand; 200 } 201 bool evaluateDot(const char*& script, bool suppressed); 202 bool evaluateDotParam(const char*& script, bool suppressed, const char* field, size_t fieldLength); 203 bool functionParams(const char** scriptPtr, SkTDArray<SkScriptValue>& params); 204 bool handleArrayIndexer(const char** scriptPtr, bool suppressed); 205 bool handleBox(SkScriptValue* value); 206 bool handleFunction(const char** scriptPtr, bool suppressed); 207 bool handleMember(const char* field, size_t len, void* object); 208 bool handleMemberFunction(const char* field, size_t len, void* object, SkTDArray<SkScriptValue>& params); 209 // bool handleObjectToString(void* object); 210 bool handleProperty(bool suppressed); 211 bool handleUnbox(SkScriptValue* scriptValue); 212 bool innerScript(const char** scriptPtr, SkScriptValue* value); 213 int logicalOp(char ch, char nextChar); 214 Error opError(); 215 bool processOp(); setAnimateMaker(SkAnimateMaker * maker)216 void setAnimateMaker(SkAnimateMaker* maker) { fMaker = maker; } 217 bool setError(Error , const char* pos); 218 enum SkBraceStyle { 219 // kStructBrace, 220 kArrayBrace, 221 kFunctionBrace 222 }; 223 224 #if 0 225 SkIntArray(SkBraceStyle) fBraceStack; // curly, square, function paren 226 SkIntArray(SkOp) fOpStack; 227 SkIntArray(SkOpType) fTypeStack; 228 SkTDOperandArray fOperandStack; 229 SkTDArray<SkSuppress> fSuppressStack; 230 #else 231 SkTDStack<SkBraceStyle> fBraceStack; // curly, square, function paren 232 SkTDStack<SkOp> fOpStack; 233 SkTDStack<SkOpType> fTypeStack; 234 SkTDStack<SkOperand> fOperandStack; 235 SkTDStack<SkSuppress> fSuppressStack; 236 #endif 237 SkAnimateMaker* fMaker; 238 SkTDTypedArrayArray fTrackArray; 239 SkTDStringArray fTrackString; 240 const char* fToken; // one-deep stack 241 size_t fTokenLength; 242 SkTDArray<UserCallBack> fUserCallBacks; 243 SkOpType fReturnType; 244 Error fError; 245 int fErrorPosition; 246 private: 247 friend class SkTypedArray; 248 #ifdef SK_SUPPORT_UNITTEST 249 public: 250 static void UnitTest(); 251 #endif 252 }; 253 254 #ifdef SK_SUPPORT_UNITTEST 255 256 struct SkScriptNAnswer { 257 const char* fScript; 258 SkDisplayTypes fType; 259 int32_t fIntAnswer; 260 SkScalar fScalarAnswer; 261 const char* fStringAnswer; 262 }; 263 264 #endif 265 266 #endif // SkScript_DEFINED 267