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; |
-} |
- |