aboutsummaryrefslogtreecommitdiffstats
path: root/src/animator/SkScriptDecompile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/animator/SkScriptDecompile.cpp')
-rw-r--r--src/animator/SkScriptDecompile.cpp221
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