diff options
Diffstat (limited to 'src/animator/SkScriptDecompile.cpp')
-rw-r--r-- | src/animator/SkScriptDecompile.cpp | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/src/animator/SkScriptDecompile.cpp b/src/animator/SkScriptDecompile.cpp new file mode 100644 index 0000000..d582d33 --- /dev/null +++ b/src/animator/SkScriptDecompile.cpp @@ -0,0 +1,221 @@ +/* libs/graphics/animator/SkScriptDecompile.cpp +** +** Copyright 2006, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +#include "SkScript2.h" + +#ifdef SK_DEBUG + +#define TypeOpName(op) {SkScriptEngine2::op, #op } + +static const struct OpName { + SkScriptEngine2::TypeOp fOp; + const char* fName; +} gOpNames[] = { + TypeOpName(kNop), // should never get generated + TypeOpName(kAccumulatorPop), + TypeOpName(kAccumulatorPush), + TypeOpName(kAddInt), + TypeOpName(kAddScalar), + TypeOpName(kAddString), // string concat + TypeOpName(kArrayIndex), + TypeOpName(kArrayParam), + TypeOpName(kArrayToken), + TypeOpName(kBitAndInt), + TypeOpName(kBitNotInt), + TypeOpName(kBitOrInt), + TypeOpName(kBoxToken), + TypeOpName(kCallback), + TypeOpName(kDivideInt), + TypeOpName(kDivideScalar), + TypeOpName(kDotOperator), + TypeOpName(kElseOp), + TypeOpName(kEnd), + TypeOpName(kEqualInt), + TypeOpName(kEqualScalar), + TypeOpName(kEqualString), + TypeOpName(kFunctionCall), + TypeOpName(kFlipOpsOp), + TypeOpName(kFunctionToken), + TypeOpName(kGreaterEqualInt), + TypeOpName(kGreaterEqualScalar), + TypeOpName(kGreaterEqualString), + TypeOpName(kIfOp), + TypeOpName(kIntToScalar), + TypeOpName(kIntToScalar2), + TypeOpName(kIntToString), + TypeOpName(kIntToString2), + TypeOpName(kIntegerAccumulator), + TypeOpName(kIntegerOperand), + TypeOpName(kLogicalAndInt), + TypeOpName(kLogicalNotInt), + TypeOpName(kLogicalOrInt), + TypeOpName(kMemberOp), + TypeOpName(kMinusInt), + TypeOpName(kMinusScalar), + TypeOpName(kModuloInt), + TypeOpName(kModuloScalar), + TypeOpName(kMultiplyInt), + TypeOpName(kMultiplyScalar), + TypeOpName(kPropertyOp), + TypeOpName(kScalarAccumulator), + TypeOpName(kScalarOperand), + TypeOpName(kScalarToInt), + TypeOpName(kScalarToInt2), + TypeOpName(kScalarToString), + TypeOpName(kScalarToString2), + TypeOpName(kShiftLeftInt), + TypeOpName(kShiftRightInt), // signed + TypeOpName(kStringAccumulator), + TypeOpName(kStringOperand), + TypeOpName(kStringToInt), + TypeOpName(kStringToScalar), + TypeOpName(kStringToScalar2), + TypeOpName(kStringTrack), + TypeOpName(kSubtractInt), + TypeOpName(kSubtractScalar), + TypeOpName(kToBool), + TypeOpName(kUnboxToken), + TypeOpName(kUnboxToken2), + TypeOpName(kXorInt) +}; + +static size_t gOpNamesSize = sizeof(gOpNames) / sizeof(gOpNames[0]); + +#define OperandName(op) {SkOperand2::op, #op } + +static const struct OperName { + SkOperand2::OpType fType; + const char* fName; +} gOperandNames[] = { + OperandName(kNoType), + OperandName(kS32), + OperandName(kScalar), + OperandName(kString), + OperandName(kArray), + OperandName(kObject) +}; + +static size_t gOperandNamesSize = sizeof(gOperandNames) / sizeof(gOperandNames[0]); + +// check to see that there are no missing or duplicate entries +void SkScriptEngine2::ValidateDecompileTable() { + SkScriptEngine2::TypeOp op = SkScriptEngine2::kNop; + int index; + for (index = 0; index < gOpNamesSize; index++) { + SkASSERT(gOpNames[index].fOp == op); + op = (SkScriptEngine2::TypeOp) (op + 1); + } + index = 0; + SkOperand2::OpType type = SkOperand2::kNoType; + SkASSERT(gOperandNames[index].fType == type); + for (; index < gOperandNamesSize - 1; ) { + type = (SkOperand2::OpType) (1 << index); + SkASSERT(gOperandNames[++index].fType == type); + } +} + +void SkScriptEngine2::decompile(const unsigned char* start, size_t length) { + SkASSERT(length > 0); + const unsigned char* opCode = start; + do { + SkASSERT(opCode - start < length); + SkScriptEngine2::TypeOp op = (SkScriptEngine2::TypeOp) *opCode++; + SkASSERT(op < gOpNamesSize); + SkDebugf("%d: %s", opCode - start - 1, gOpNames[op].fName); + switch (op) { + case SkScriptEngine2::kCallback: { + int index; + memcpy(&index, opCode, sizeof(index)); + opCode += sizeof(index); + SkDebugf(" index: %d", index); + } break; + case SkScriptEngine2::kFunctionCall: + case SkScriptEngine2::kMemberOp: + case SkScriptEngine2::kPropertyOp: { + size_t ref; + memcpy(&ref, opCode, sizeof(ref)); + opCode += sizeof(ref); + SkDebugf(" ref: %d", ref); + } break; + case SkScriptEngine2::kIntegerAccumulator: + case SkScriptEngine2::kIntegerOperand: { + int32_t integer; + memcpy(&integer, opCode, sizeof(integer)); + opCode += sizeof(int32_t); + SkDebugf(" integer: %d", integer); + } break; + case SkScriptEngine2::kScalarAccumulator: + case SkScriptEngine2::kScalarOperand: { + SkScalar scalar; + memcpy(&scalar, opCode, sizeof(scalar)); + opCode += sizeof(SkScalar); +#ifdef SK_CAN_USE_FLOAT + SkDebugf(" scalar: %g", SkScalarToFloat(scalar)); +#else + SkDebugf(" scalar: %x", scalar); +#endif + } break; + case SkScriptEngine2::kStringAccumulator: + case SkScriptEngine2::kStringOperand: { + int size; + SkString* strPtr = new SkString(); + memcpy(&size, opCode, sizeof(size)); + opCode += sizeof(size); + strPtr->set((char*) opCode, size); + opCode += size; + SkDebugf(" string: %s", strPtr->c_str()); + delete strPtr; + } break; + case SkScriptEngine2::kBoxToken: { + SkOperand2::OpType type; + memcpy(&type, opCode, sizeof(type)); + opCode += sizeof(type); + int index = 0; + if (type == 0) + SkDebugf(" type: %s", gOperandNames[index].fName); + else { + while (type != 0) { + SkASSERT(index + 1 < gOperandNamesSize); + if (type & (1 << index)) { + type = (SkOperand2::OpType) (type & ~(1 << index)); + SkDebugf(" type: %s", gOperandNames[index + 1].fName); + } + index++; + } + } + } break; + case SkScriptEngine2::kIfOp: + case SkScriptEngine2::kLogicalAndInt: + case SkScriptEngine2::kElseOp: + case SkScriptEngine2::kLogicalOrInt: { + int size; + memcpy(&size, opCode, sizeof(size)); + opCode += sizeof(size); + SkDebugf(" offset (address): %d (%d)", size, opCode - start + size); + } break; + case SkScriptEngine2::kEnd: + goto done; + case SkScriptEngine2::kNop: + SkASSERT(0); + } + SkDebugf("\n"); + } while (true); +done: + SkDebugf("\n"); +} + +#endif |