| Index: skia/animator/SkScriptRuntime.cpp
|
| ===================================================================
|
| --- skia/animator/SkScriptRuntime.cpp (revision 16859)
|
| +++ skia/animator/SkScriptRuntime.cpp (working copy)
|
| @@ -1,342 +0,0 @@
|
| -#include "SkScriptRuntime.h"
|
| -#include "SkScript2.h"
|
| -#include "SkParse.h"
|
| -#include "SkScriptCallBack.h"
|
| -#include "SkString.h"
|
| -#include "SkOpArray.h"
|
| -
|
| -// script tokenizer
|
| -
|
| -// turn text into token string
|
| -// turn number literals into inline UTF8-style values
|
| -// process operators to turn standard notation into stack notation
|
| -
|
| -// defer processing until the tokens can all be resolved
|
| -// then, turn token strings into indices into the appropriate tables / dictionaries
|
| -
|
| -// consider: const evaluation?
|
| -
|
| -// replace script string with script tokens preceeded by special value
|
| -
|
| -// need second version of script plugins that return private index of found value?
|
| - // then would need in script index of plugin, private index
|
| -
|
| -// encode brace stack push/pop as opcodes
|
| -
|
| -// should token script enocde type where possible?
|
| -
|
| -// current flow:
|
| - // strip whitespace
|
| - // if in array brace [ recurse, continue
|
| - // if token, handle function, or array, or property (continue)
|
| - // parse number, continue
|
| - // parse token, continue
|
| - // parse string literal, continue
|
| - // if dot operator, handle dot, continue
|
| - // if [ , handle array literal or accessor, continue
|
| - // if ), pop (if function, break)
|
| - // if ], pop ; if ',' break
|
| - // handle logical ops
|
| - // or, handle arithmetic ops
|
| - // loop
|
| -
|
| -// !!! things to do
|
| - // add separate processing loop to advance while suppressed
|
| - // or, include jump offset to skip suppressed code?
|
| -
|
| -SkScriptRuntime::~SkScriptRuntime() {
|
| - for (SkString** stringPtr = fTrackString.begin(); stringPtr < fTrackString.end(); stringPtr++)
|
| - delete *stringPtr;
|
| - for (SkOpArray** arrayPtr = fTrackArray.begin(); arrayPtr < fTrackArray.end(); arrayPtr++)
|
| - delete *arrayPtr;
|
| -}
|
| -
|
| -bool SkScriptRuntime::executeTokens(unsigned char* opCode) {
|
| - SkOperand2 operand[2]; // 1=accumulator and 2=operand
|
| - SkScriptEngine2::TypeOp op;
|
| - size_t ref;
|
| - int index, size;
|
| - int registerLoad;
|
| - SkScriptCallBack* callBack SK_INIT_TO_AVOID_WARNING;
|
| - do {
|
| - switch ((op = (SkScriptEngine2::TypeOp) *opCode++)) {
|
| - case SkScriptEngine2::kArrayToken: // create an array
|
| - operand[0].fArray = new SkOpArray(SkOperand2::kNoType /*fReturnType*/);
|
| - break;
|
| - case SkScriptEngine2::kArrayIndex: // array accessor
|
| - index = operand[1].fS32;
|
| - if (index >= operand[0].fArray->count()) {
|
| - fError = kArrayIndexOutOfBounds;
|
| - return false;
|
| - }
|
| - operand[0] = operand[0].fArray->begin()[index];
|
| - break;
|
| - case SkScriptEngine2::kArrayParam: // array initializer, or function param
|
| - *operand[0].fArray->append() = operand[1];
|
| - break;
|
| - case SkScriptEngine2::kCallback:
|
| - memcpy(&index, opCode, sizeof(index));
|
| - opCode += sizeof(index);
|
| - callBack = fCallBackArray[index];
|
| - break;
|
| - case SkScriptEngine2::kFunctionCall: {
|
| - memcpy(&ref, opCode, sizeof(ref));
|
| - opCode += sizeof(ref);
|
| - SkScriptCallBackFunction* callBackFunction = (SkScriptCallBackFunction*) callBack;
|
| - if (callBackFunction->invoke(ref, operand[0].fArray, /* params */
|
| - &operand[0] /* result */) == false) {
|
| - fError = kFunctionCallFailed;
|
| - return false;
|
| - }
|
| - } break;
|
| - case SkScriptEngine2::kMemberOp: {
|
| - memcpy(&ref, opCode, sizeof(ref));
|
| - opCode += sizeof(ref);
|
| - SkScriptCallBackMember* callBackMember = (SkScriptCallBackMember*) callBack;
|
| - if (callBackMember->invoke(ref, operand[0].fObject, &operand[0]) == false) {
|
| - fError = kMemberOpFailed;
|
| - return false;
|
| - }
|
| - } break;
|
| - case SkScriptEngine2::kPropertyOp: {
|
| - memcpy(&ref, opCode, sizeof(ref));
|
| - opCode += sizeof(ref);
|
| - SkScriptCallBackProperty* callBackProperty = (SkScriptCallBackProperty*) callBack;
|
| - if (callBackProperty->getResult(ref, &operand[0])== false) {
|
| - fError = kPropertyOpFailed;
|
| - return false;
|
| - }
|
| - } break;
|
| - case SkScriptEngine2::kAccumulatorPop:
|
| - fRunStack.pop(&operand[0]);
|
| - break;
|
| - case SkScriptEngine2::kAccumulatorPush:
|
| - *fRunStack.push() = operand[0];
|
| - break;
|
| - case SkScriptEngine2::kIntegerAccumulator:
|
| - case SkScriptEngine2::kIntegerOperand:
|
| - registerLoad = op - SkScriptEngine2::kIntegerAccumulator;
|
| - memcpy(&operand[registerLoad].fS32, opCode, sizeof(int32_t));
|
| - opCode += sizeof(int32_t);
|
| - break;
|
| - case SkScriptEngine2::kScalarAccumulator:
|
| - case SkScriptEngine2::kScalarOperand:
|
| - registerLoad = op - SkScriptEngine2::kScalarAccumulator;
|
| - memcpy(&operand[registerLoad].fScalar, opCode, sizeof(SkScalar));
|
| - opCode += sizeof(SkScalar);
|
| - break;
|
| - case SkScriptEngine2::kStringAccumulator:
|
| - case SkScriptEngine2::kStringOperand: {
|
| - SkString* strPtr = new SkString();
|
| - track(strPtr);
|
| - registerLoad = op - SkScriptEngine2::kStringAccumulator;
|
| - memcpy(&size, opCode, sizeof(size));
|
| - opCode += sizeof(size);
|
| - strPtr->set((char*) opCode, size);
|
| - opCode += size;
|
| - operand[registerLoad].fString = strPtr;
|
| - } break;
|
| - case SkScriptEngine2::kStringTrack: // call after kObjectToValue
|
| - track(operand[0].fString);
|
| - break;
|
| - case SkScriptEngine2::kBoxToken: {
|
| - SkOperand2::OpType type;
|
| - memcpy(&type, opCode, sizeof(type));
|
| - opCode += sizeof(type);
|
| - SkScriptCallBackConvert* callBackBox = (SkScriptCallBackConvert*) callBack;
|
| - if (callBackBox->convert(type, &operand[0]) == false)
|
| - return false;
|
| - } break;
|
| - case SkScriptEngine2::kUnboxToken:
|
| - case SkScriptEngine2::kUnboxToken2: {
|
| - SkScriptCallBackConvert* callBackUnbox = (SkScriptCallBackConvert*) callBack;
|
| - if (callBackUnbox->convert(SkOperand2::kObject, &operand[0]) == false)
|
| - return false;
|
| - } break;
|
| - case SkScriptEngine2::kIfOp:
|
| - case SkScriptEngine2::kLogicalAndInt:
|
| - memcpy(&size, opCode, sizeof(size));
|
| - opCode += sizeof(size);
|
| - if (operand[0].fS32 == 0)
|
| - opCode += size; // skip to else (or end of if predicate)
|
| - break;
|
| - case SkScriptEngine2::kElseOp:
|
| - memcpy(&size, opCode, sizeof(size));
|
| - opCode += sizeof(size);
|
| - opCode += size; // if true: after predicate, always skip to end of else
|
| - break;
|
| - case SkScriptEngine2::kLogicalOrInt:
|
| - memcpy(&size, opCode, sizeof(size));
|
| - opCode += sizeof(size);
|
| - if (operand[0].fS32 != 0)
|
| - opCode += size; // skip to kToBool opcode after || predicate
|
| - break;
|
| - // arithmetic conversion ops
|
| - case SkScriptEngine2::kFlipOpsOp:
|
| - SkTSwap(operand[0], operand[1]);
|
| - break;
|
| - case SkScriptEngine2::kIntToString:
|
| - case SkScriptEngine2::kIntToString2:
|
| - case SkScriptEngine2::kScalarToString:
|
| - case SkScriptEngine2::kScalarToString2:{
|
| - SkString* strPtr = new SkString();
|
| - track(strPtr);
|
| - if (op == SkScriptEngine2::kIntToString || op == SkScriptEngine2::kIntToString2)
|
| - strPtr->appendS32(operand[op - SkScriptEngine2::kIntToString].fS32);
|
| - else
|
| - strPtr->appendScalar(operand[op - SkScriptEngine2::kScalarToString].fScalar);
|
| - operand[0].fString = strPtr;
|
| - } break;
|
| - case SkScriptEngine2::kIntToScalar:
|
| - case SkScriptEngine2::kIntToScalar2:
|
| - operand[0].fScalar = SkScriptEngine2::IntToScalar(operand[op - SkScriptEngine2::kIntToScalar].fS32);
|
| - break;
|
| - case SkScriptEngine2::kStringToInt:
|
| - if (SkParse::FindS32(operand[0].fString->c_str(), &operand[0].fS32) == false)
|
| - return false;
|
| - break;
|
| - case SkScriptEngine2::kStringToScalar:
|
| - case SkScriptEngine2::kStringToScalar2:
|
| - if (SkParse::FindScalar(operand[0].fString->c_str(),
|
| - &operand[op - SkScriptEngine2::kStringToScalar].fScalar) == false)
|
| - return false;
|
| - break;
|
| - case SkScriptEngine2::kScalarToInt:
|
| - operand[0].fS32 = SkScalarFloor(operand[0].fScalar);
|
| - break;
|
| - // arithmetic ops
|
| - case SkScriptEngine2::kAddInt:
|
| - operand[0].fS32 += operand[1].fS32;
|
| - break;
|
| - case SkScriptEngine2::kAddScalar:
|
| - operand[0].fScalar += operand[1].fScalar;
|
| - break;
|
| - case SkScriptEngine2::kAddString:
|
| -// if (fTrackString.find(operand[1].fString) < 0) {
|
| -// operand[1].fString = SkNEW_ARGS(SkString, (*operand[1].fString));
|
| -// track(operand[1].fString);
|
| -// }
|
| - operand[0].fString->append(*operand[1].fString);
|
| - break;
|
| - case SkScriptEngine2::kBitAndInt:
|
| - operand[0].fS32 &= operand[1].fS32;
|
| - break;
|
| - case SkScriptEngine2::kBitNotInt:
|
| - operand[0].fS32 = ~operand[0].fS32;
|
| - break;
|
| - case SkScriptEngine2::kBitOrInt:
|
| - operand[0].fS32 |= operand[1].fS32;
|
| - break;
|
| - case SkScriptEngine2::kDivideInt:
|
| - SkASSERT(operand[1].fS32 != 0);
|
| - if (operand[1].fS32 == 0)
|
| - operand[0].fS32 = operand[0].fS32 == 0 ? SK_NaN32 :
|
| - operand[0].fS32 > 0 ? SK_MaxS32 : -SK_MaxS32;
|
| - else
|
| - if (operand[1].fS32 != 0) // throw error on divide by zero?
|
| - operand[0].fS32 /= operand[1].fS32;
|
| - break;
|
| - case SkScriptEngine2::kDivideScalar:
|
| - if (operand[1].fScalar == 0)
|
| - operand[0].fScalar = operand[0].fScalar == 0 ? SK_ScalarNaN :
|
| - operand[0].fScalar > 0 ? SK_ScalarMax : -SK_ScalarMax;
|
| - else
|
| - operand[0].fScalar = SkScalarDiv(operand[0].fScalar, operand[1].fScalar);
|
| - break;
|
| - case SkScriptEngine2::kEqualInt:
|
| - operand[0].fS32 = operand[0].fS32 == operand[1].fS32;
|
| - break;
|
| - case SkScriptEngine2::kEqualScalar:
|
| - operand[0].fS32 = operand[0].fScalar == operand[1].fScalar;
|
| - break;
|
| - case SkScriptEngine2::kEqualString:
|
| - operand[0].fS32 = *operand[0].fString == *operand[1].fString;
|
| - break;
|
| - case SkScriptEngine2::kGreaterEqualInt:
|
| - operand[0].fS32 = operand[0].fS32 >= operand[1].fS32;
|
| - break;
|
| - case SkScriptEngine2::kGreaterEqualScalar:
|
| - operand[0].fS32 = operand[0].fScalar >= operand[1].fScalar;
|
| - break;
|
| - case SkScriptEngine2::kGreaterEqualString:
|
| - operand[0].fS32 = strcmp(operand[0].fString->c_str(), operand[1].fString->c_str()) >= 0;
|
| - break;
|
| - case SkScriptEngine2::kToBool:
|
| - operand[0].fS32 = !! operand[0].fS32;
|
| - break;
|
| - case SkScriptEngine2::kLogicalNotInt:
|
| - operand[0].fS32 = ! operand[0].fS32;
|
| - break;
|
| - case SkScriptEngine2::kMinusInt:
|
| - operand[0].fS32 = -operand[0].fS32;
|
| - break;
|
| - case SkScriptEngine2::kMinusScalar:
|
| - operand[0].fScalar = -operand[0].fScalar;
|
| - break;
|
| - case SkScriptEngine2::kModuloInt:
|
| - operand[0].fS32 %= operand[1].fS32;
|
| - break;
|
| - case SkScriptEngine2::kModuloScalar:
|
| - operand[0].fScalar = SkScalarMod(operand[0].fScalar, operand[1].fScalar);
|
| - break;
|
| - case SkScriptEngine2::kMultiplyInt:
|
| - operand[0].fS32 *= operand[1].fS32;
|
| - break;
|
| - case SkScriptEngine2::kMultiplyScalar:
|
| - operand[0].fScalar = SkScalarMul(operand[0].fScalar, operand[1].fScalar);
|
| - break;
|
| - case SkScriptEngine2::kShiftLeftInt:
|
| - operand[0].fS32 <<= operand[1].fS32;
|
| - break;
|
| - case SkScriptEngine2::kShiftRightInt:
|
| - operand[0].fS32 >>= operand[1].fS32;
|
| - break;
|
| - case SkScriptEngine2::kSubtractInt:
|
| - operand[0].fS32 -= operand[1].fS32;
|
| - break;
|
| - case SkScriptEngine2::kSubtractScalar:
|
| - operand[0].fScalar -= operand[1].fScalar;
|
| - break;
|
| - case SkScriptEngine2::kXorInt:
|
| - operand[0].fS32 ^= operand[1].fS32;
|
| - break;
|
| - case SkScriptEngine2::kEnd:
|
| - goto done;
|
| - case SkScriptEngine2::kNop:
|
| - SkASSERT(0);
|
| - }
|
| - } while (true);
|
| -done:
|
| - fRunStack.push(operand[0]);
|
| - return true;
|
| -}
|
| -
|
| -bool SkScriptRuntime::getResult(SkOperand2* result) {
|
| - if (fRunStack.count() == 0)
|
| - return false;
|
| - fRunStack.pop(result);
|
| - return true;
|
| -}
|
| -
|
| -void SkScriptRuntime::track(SkOpArray* array) {
|
| - SkASSERT(fTrackArray.find(array) < 0);
|
| - *fTrackArray.append() = array;
|
| -}
|
| -
|
| -void SkScriptRuntime::track(SkString* string) {
|
| - SkASSERT(fTrackString.find(string) < 0);
|
| - *fTrackString.append() = string;
|
| -}
|
| -
|
| -void SkScriptRuntime::untrack(SkOpArray* array) {
|
| - int index = fTrackArray.find(array);
|
| - SkASSERT(index >= 0);
|
| - fTrackArray.begin()[index] = NULL;
|
| -}
|
| -
|
| -void SkScriptRuntime::untrack(SkString* string) {
|
| - int index = fTrackString.find(string);
|
| - SkASSERT(index >= 0);
|
| - fTrackString.begin()[index] = NULL;
|
| -}
|
| -
|
|
|