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