gfx/skia/trunk/src/animator/SkScriptRuntime.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

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 #include "SkScriptRuntime.h"
michael@0 9 #include "SkScript2.h"
michael@0 10 #include "SkMath.h"
michael@0 11 #include "SkParse.h"
michael@0 12 #include "SkScriptCallBack.h"
michael@0 13 #include "SkString.h"
michael@0 14 #include "SkOpArray.h"
michael@0 15
michael@0 16 // script tokenizer
michael@0 17
michael@0 18 // turn text into token string
michael@0 19 // turn number literals into inline UTF8-style values
michael@0 20 // process operators to turn standard notation into stack notation
michael@0 21
michael@0 22 // defer processing until the tokens can all be resolved
michael@0 23 // then, turn token strings into indices into the appropriate tables / dictionaries
michael@0 24
michael@0 25 // consider: const evaluation?
michael@0 26
michael@0 27 // replace script string with script tokens preceeded by special value
michael@0 28
michael@0 29 // need second version of script plugins that return private index of found value?
michael@0 30 // then would need in script index of plugin, private index
michael@0 31
michael@0 32 // encode brace stack push/pop as opcodes
michael@0 33
michael@0 34 // should token script enocde type where possible?
michael@0 35
michael@0 36 // current flow:
michael@0 37 // strip whitespace
michael@0 38 // if in array brace [ recurse, continue
michael@0 39 // if token, handle function, or array, or property (continue)
michael@0 40 // parse number, continue
michael@0 41 // parse token, continue
michael@0 42 // parse string literal, continue
michael@0 43 // if dot operator, handle dot, continue
michael@0 44 // if [ , handle array literal or accessor, continue
michael@0 45 // if ), pop (if function, break)
michael@0 46 // if ], pop ; if ',' break
michael@0 47 // handle logical ops
michael@0 48 // or, handle arithmetic ops
michael@0 49 // loop
michael@0 50
michael@0 51 // !!! things to do
michael@0 52 // add separate processing loop to advance while suppressed
michael@0 53 // or, include jump offset to skip suppressed code?
michael@0 54
michael@0 55 SkScriptRuntime::~SkScriptRuntime() {
michael@0 56 for (SkString** stringPtr = fTrackString.begin(); stringPtr < fTrackString.end(); stringPtr++)
michael@0 57 delete *stringPtr;
michael@0 58 for (SkOpArray** arrayPtr = fTrackArray.begin(); arrayPtr < fTrackArray.end(); arrayPtr++)
michael@0 59 delete *arrayPtr;
michael@0 60 }
michael@0 61
michael@0 62 bool SkScriptRuntime::executeTokens(unsigned char* opCode) {
michael@0 63 SkOperand2 operand[2]; // 1=accumulator and 2=operand
michael@0 64 SkScriptEngine2::TypeOp op;
michael@0 65 size_t ref;
michael@0 66 int index, size;
michael@0 67 int registerLoad;
michael@0 68 SkScriptCallBack* callBack SK_INIT_TO_AVOID_WARNING;
michael@0 69 do {
michael@0 70 switch ((op = (SkScriptEngine2::TypeOp) *opCode++)) {
michael@0 71 case SkScriptEngine2::kArrayToken: // create an array
michael@0 72 operand[0].fArray = new SkOpArray(SkOperand2::kNoType /*fReturnType*/);
michael@0 73 break;
michael@0 74 case SkScriptEngine2::kArrayIndex: // array accessor
michael@0 75 index = operand[1].fS32;
michael@0 76 if (index >= operand[0].fArray->count()) {
michael@0 77 fError = kArrayIndexOutOfBounds;
michael@0 78 return false;
michael@0 79 }
michael@0 80 operand[0] = operand[0].fArray->begin()[index];
michael@0 81 break;
michael@0 82 case SkScriptEngine2::kArrayParam: // array initializer, or function param
michael@0 83 *operand[0].fArray->append() = operand[1];
michael@0 84 break;
michael@0 85 case SkScriptEngine2::kCallback:
michael@0 86 memcpy(&index, opCode, sizeof(index));
michael@0 87 opCode += sizeof(index);
michael@0 88 callBack = fCallBackArray[index];
michael@0 89 break;
michael@0 90 case SkScriptEngine2::kFunctionCall: {
michael@0 91 memcpy(&ref, opCode, sizeof(ref));
michael@0 92 opCode += sizeof(ref);
michael@0 93 SkScriptCallBackFunction* callBackFunction = (SkScriptCallBackFunction*) callBack;
michael@0 94 if (callBackFunction->invoke(ref, operand[0].fArray, /* params */
michael@0 95 &operand[0] /* result */) == false) {
michael@0 96 fError = kFunctionCallFailed;
michael@0 97 return false;
michael@0 98 }
michael@0 99 } break;
michael@0 100 case SkScriptEngine2::kMemberOp: {
michael@0 101 memcpy(&ref, opCode, sizeof(ref));
michael@0 102 opCode += sizeof(ref);
michael@0 103 SkScriptCallBackMember* callBackMember = (SkScriptCallBackMember*) callBack;
michael@0 104 if (callBackMember->invoke(ref, operand[0].fObject, &operand[0]) == false) {
michael@0 105 fError = kMemberOpFailed;
michael@0 106 return false;
michael@0 107 }
michael@0 108 } break;
michael@0 109 case SkScriptEngine2::kPropertyOp: {
michael@0 110 memcpy(&ref, opCode, sizeof(ref));
michael@0 111 opCode += sizeof(ref);
michael@0 112 SkScriptCallBackProperty* callBackProperty = (SkScriptCallBackProperty*) callBack;
michael@0 113 if (callBackProperty->getResult(ref, &operand[0])== false) {
michael@0 114 fError = kPropertyOpFailed;
michael@0 115 return false;
michael@0 116 }
michael@0 117 } break;
michael@0 118 case SkScriptEngine2::kAccumulatorPop:
michael@0 119 fRunStack.pop(&operand[0]);
michael@0 120 break;
michael@0 121 case SkScriptEngine2::kAccumulatorPush:
michael@0 122 *fRunStack.push() = operand[0];
michael@0 123 break;
michael@0 124 case SkScriptEngine2::kIntegerAccumulator:
michael@0 125 case SkScriptEngine2::kIntegerOperand:
michael@0 126 registerLoad = op - SkScriptEngine2::kIntegerAccumulator;
michael@0 127 memcpy(&operand[registerLoad].fS32, opCode, sizeof(int32_t));
michael@0 128 opCode += sizeof(int32_t);
michael@0 129 break;
michael@0 130 case SkScriptEngine2::kScalarAccumulator:
michael@0 131 case SkScriptEngine2::kScalarOperand:
michael@0 132 registerLoad = op - SkScriptEngine2::kScalarAccumulator;
michael@0 133 memcpy(&operand[registerLoad].fScalar, opCode, sizeof(SkScalar));
michael@0 134 opCode += sizeof(SkScalar);
michael@0 135 break;
michael@0 136 case SkScriptEngine2::kStringAccumulator:
michael@0 137 case SkScriptEngine2::kStringOperand: {
michael@0 138 SkString* strPtr = new SkString();
michael@0 139 track(strPtr);
michael@0 140 registerLoad = op - SkScriptEngine2::kStringAccumulator;
michael@0 141 memcpy(&size, opCode, sizeof(size));
michael@0 142 opCode += sizeof(size);
michael@0 143 strPtr->set((char*) opCode, size);
michael@0 144 opCode += size;
michael@0 145 operand[registerLoad].fString = strPtr;
michael@0 146 } break;
michael@0 147 case SkScriptEngine2::kStringTrack: // call after kObjectToValue
michael@0 148 track(operand[0].fString);
michael@0 149 break;
michael@0 150 case SkScriptEngine2::kBoxToken: {
michael@0 151 SkOperand2::OpType type;
michael@0 152 memcpy(&type, opCode, sizeof(type));
michael@0 153 opCode += sizeof(type);
michael@0 154 SkScriptCallBackConvert* callBackBox = (SkScriptCallBackConvert*) callBack;
michael@0 155 if (callBackBox->convert(type, &operand[0]) == false)
michael@0 156 return false;
michael@0 157 } break;
michael@0 158 case SkScriptEngine2::kUnboxToken:
michael@0 159 case SkScriptEngine2::kUnboxToken2: {
michael@0 160 SkScriptCallBackConvert* callBackUnbox = (SkScriptCallBackConvert*) callBack;
michael@0 161 if (callBackUnbox->convert(SkOperand2::kObject, &operand[0]) == false)
michael@0 162 return false;
michael@0 163 } break;
michael@0 164 case SkScriptEngine2::kIfOp:
michael@0 165 case SkScriptEngine2::kLogicalAndInt:
michael@0 166 memcpy(&size, opCode, sizeof(size));
michael@0 167 opCode += sizeof(size);
michael@0 168 if (operand[0].fS32 == 0)
michael@0 169 opCode += size; // skip to else (or end of if predicate)
michael@0 170 break;
michael@0 171 case SkScriptEngine2::kElseOp:
michael@0 172 memcpy(&size, opCode, sizeof(size));
michael@0 173 opCode += sizeof(size);
michael@0 174 opCode += size; // if true: after predicate, always skip to end of else
michael@0 175 break;
michael@0 176 case SkScriptEngine2::kLogicalOrInt:
michael@0 177 memcpy(&size, opCode, sizeof(size));
michael@0 178 opCode += sizeof(size);
michael@0 179 if (operand[0].fS32 != 0)
michael@0 180 opCode += size; // skip to kToBool opcode after || predicate
michael@0 181 break;
michael@0 182 // arithmetic conversion ops
michael@0 183 case SkScriptEngine2::kFlipOpsOp:
michael@0 184 SkTSwap(operand[0], operand[1]);
michael@0 185 break;
michael@0 186 case SkScriptEngine2::kIntToString:
michael@0 187 case SkScriptEngine2::kIntToString2:
michael@0 188 case SkScriptEngine2::kScalarToString:
michael@0 189 case SkScriptEngine2::kScalarToString2:{
michael@0 190 SkString* strPtr = new SkString();
michael@0 191 track(strPtr);
michael@0 192 if (op == SkScriptEngine2::kIntToString || op == SkScriptEngine2::kIntToString2)
michael@0 193 strPtr->appendS32(operand[op - SkScriptEngine2::kIntToString].fS32);
michael@0 194 else
michael@0 195 strPtr->appendScalar(operand[op - SkScriptEngine2::kScalarToString].fScalar);
michael@0 196 operand[0].fString = strPtr;
michael@0 197 } break;
michael@0 198 case SkScriptEngine2::kIntToScalar:
michael@0 199 case SkScriptEngine2::kIntToScalar2:
michael@0 200 operand[0].fScalar = SkScriptEngine2::IntToScalar(operand[op - SkScriptEngine2::kIntToScalar].fS32);
michael@0 201 break;
michael@0 202 case SkScriptEngine2::kStringToInt:
michael@0 203 if (SkParse::FindS32(operand[0].fString->c_str(), &operand[0].fS32) == NULL)
michael@0 204 return false;
michael@0 205 break;
michael@0 206 case SkScriptEngine2::kStringToScalar:
michael@0 207 case SkScriptEngine2::kStringToScalar2:
michael@0 208 if (SkParse::FindScalar(operand[0].fString->c_str(),
michael@0 209 &operand[op - SkScriptEngine2::kStringToScalar].fScalar) == NULL)
michael@0 210 return false;
michael@0 211 break;
michael@0 212 case SkScriptEngine2::kScalarToInt:
michael@0 213 operand[0].fS32 = SkScalarFloorToInt(operand[0].fScalar);
michael@0 214 break;
michael@0 215 // arithmetic ops
michael@0 216 case SkScriptEngine2::kAddInt:
michael@0 217 operand[0].fS32 += operand[1].fS32;
michael@0 218 break;
michael@0 219 case SkScriptEngine2::kAddScalar:
michael@0 220 operand[0].fScalar += operand[1].fScalar;
michael@0 221 break;
michael@0 222 case SkScriptEngine2::kAddString:
michael@0 223 // if (fTrackString.find(operand[1].fString) < 0) {
michael@0 224 // operand[1].fString = SkNEW_ARGS(SkString, (*operand[1].fString));
michael@0 225 // track(operand[1].fString);
michael@0 226 // }
michael@0 227 operand[0].fString->append(*operand[1].fString);
michael@0 228 break;
michael@0 229 case SkScriptEngine2::kBitAndInt:
michael@0 230 operand[0].fS32 &= operand[1].fS32;
michael@0 231 break;
michael@0 232 case SkScriptEngine2::kBitNotInt:
michael@0 233 operand[0].fS32 = ~operand[0].fS32;
michael@0 234 break;
michael@0 235 case SkScriptEngine2::kBitOrInt:
michael@0 236 operand[0].fS32 |= operand[1].fS32;
michael@0 237 break;
michael@0 238 case SkScriptEngine2::kDivideInt:
michael@0 239 SkASSERT(operand[1].fS32 != 0);
michael@0 240 if (operand[1].fS32 == 0)
michael@0 241 operand[0].fS32 = operand[0].fS32 == 0 ? SK_NaN32 :
michael@0 242 operand[0].fS32 > 0 ? SK_MaxS32 : -SK_MaxS32;
michael@0 243 else
michael@0 244 if (operand[1].fS32 != 0) // throw error on divide by zero?
michael@0 245 operand[0].fS32 /= operand[1].fS32;
michael@0 246 break;
michael@0 247 case SkScriptEngine2::kDivideScalar:
michael@0 248 if (operand[1].fScalar == 0)
michael@0 249 operand[0].fScalar = operand[0].fScalar == 0 ? SK_ScalarNaN :
michael@0 250 operand[0].fScalar > 0 ? SK_ScalarMax : -SK_ScalarMax;
michael@0 251 else
michael@0 252 operand[0].fScalar = SkScalarDiv(operand[0].fScalar, operand[1].fScalar);
michael@0 253 break;
michael@0 254 case SkScriptEngine2::kEqualInt:
michael@0 255 operand[0].fS32 = operand[0].fS32 == operand[1].fS32;
michael@0 256 break;
michael@0 257 case SkScriptEngine2::kEqualScalar:
michael@0 258 operand[0].fS32 = operand[0].fScalar == operand[1].fScalar;
michael@0 259 break;
michael@0 260 case SkScriptEngine2::kEqualString:
michael@0 261 operand[0].fS32 = *operand[0].fString == *operand[1].fString;
michael@0 262 break;
michael@0 263 case SkScriptEngine2::kGreaterEqualInt:
michael@0 264 operand[0].fS32 = operand[0].fS32 >= operand[1].fS32;
michael@0 265 break;
michael@0 266 case SkScriptEngine2::kGreaterEqualScalar:
michael@0 267 operand[0].fS32 = operand[0].fScalar >= operand[1].fScalar;
michael@0 268 break;
michael@0 269 case SkScriptEngine2::kGreaterEqualString:
michael@0 270 operand[0].fS32 = strcmp(operand[0].fString->c_str(), operand[1].fString->c_str()) >= 0;
michael@0 271 break;
michael@0 272 case SkScriptEngine2::kToBool:
michael@0 273 operand[0].fS32 = !! operand[0].fS32;
michael@0 274 break;
michael@0 275 case SkScriptEngine2::kLogicalNotInt:
michael@0 276 operand[0].fS32 = ! operand[0].fS32;
michael@0 277 break;
michael@0 278 case SkScriptEngine2::kMinusInt:
michael@0 279 operand[0].fS32 = -operand[0].fS32;
michael@0 280 break;
michael@0 281 case SkScriptEngine2::kMinusScalar:
michael@0 282 operand[0].fScalar = -operand[0].fScalar;
michael@0 283 break;
michael@0 284 case SkScriptEngine2::kModuloInt:
michael@0 285 operand[0].fS32 %= operand[1].fS32;
michael@0 286 break;
michael@0 287 case SkScriptEngine2::kModuloScalar:
michael@0 288 operand[0].fScalar = SkScalarMod(operand[0].fScalar, operand[1].fScalar);
michael@0 289 break;
michael@0 290 case SkScriptEngine2::kMultiplyInt:
michael@0 291 operand[0].fS32 *= operand[1].fS32;
michael@0 292 break;
michael@0 293 case SkScriptEngine2::kMultiplyScalar:
michael@0 294 operand[0].fScalar = SkScalarMul(operand[0].fScalar, operand[1].fScalar);
michael@0 295 break;
michael@0 296 case SkScriptEngine2::kShiftLeftInt:
michael@0 297 operand[0].fS32 <<= operand[1].fS32;
michael@0 298 break;
michael@0 299 case SkScriptEngine2::kShiftRightInt:
michael@0 300 operand[0].fS32 >>= operand[1].fS32;
michael@0 301 break;
michael@0 302 case SkScriptEngine2::kSubtractInt:
michael@0 303 operand[0].fS32 -= operand[1].fS32;
michael@0 304 break;
michael@0 305 case SkScriptEngine2::kSubtractScalar:
michael@0 306 operand[0].fScalar -= operand[1].fScalar;
michael@0 307 break;
michael@0 308 case SkScriptEngine2::kXorInt:
michael@0 309 operand[0].fS32 ^= operand[1].fS32;
michael@0 310 break;
michael@0 311 case SkScriptEngine2::kEnd:
michael@0 312 goto done;
michael@0 313 case SkScriptEngine2::kNop:
michael@0 314 SkASSERT(0);
michael@0 315 default:
michael@0 316 break;
michael@0 317 }
michael@0 318 } while (true);
michael@0 319 done:
michael@0 320 fRunStack.push(operand[0]);
michael@0 321 return true;
michael@0 322 }
michael@0 323
michael@0 324 bool SkScriptRuntime::getResult(SkOperand2* result) {
michael@0 325 if (fRunStack.count() == 0)
michael@0 326 return false;
michael@0 327 fRunStack.pop(result);
michael@0 328 return true;
michael@0 329 }
michael@0 330
michael@0 331 void SkScriptRuntime::track(SkOpArray* array) {
michael@0 332 SkASSERT(fTrackArray.find(array) < 0);
michael@0 333 *fTrackArray.append() = array;
michael@0 334 }
michael@0 335
michael@0 336 void SkScriptRuntime::track(SkString* string) {
michael@0 337 SkASSERT(fTrackString.find(string) < 0);
michael@0 338 *fTrackString.append() = string;
michael@0 339 }
michael@0 340
michael@0 341 void SkScriptRuntime::untrack(SkOpArray* array) {
michael@0 342 int index = fTrackArray.find(array);
michael@0 343 SkASSERT(index >= 0);
michael@0 344 fTrackArray.begin()[index] = NULL;
michael@0 345 }
michael@0 346
michael@0 347 void SkScriptRuntime::untrack(SkString* string) {
michael@0 348 int index = fTrackString.find(string);
michael@0 349 SkASSERT(index >= 0);
michael@0 350 fTrackString.begin()[index] = NULL;
michael@0 351 }

mercurial