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.

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

mercurial