1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/animator/SkScriptDecompile.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,211 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2006 The Android Open Source Project 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 + 1.12 + 1.13 +#include "SkScript2.h" 1.14 + 1.15 +#ifdef SK_DEBUG 1.16 + 1.17 +#define TypeOpName(op) {SkScriptEngine2::op, #op } 1.18 + 1.19 +static const struct OpName { 1.20 + SkScriptEngine2::TypeOp fOp; 1.21 + const char* fName; 1.22 +} gOpNames[] = { 1.23 + TypeOpName(kNop), // should never get generated 1.24 + TypeOpName(kAccumulatorPop), 1.25 + TypeOpName(kAccumulatorPush), 1.26 + TypeOpName(kAddInt), 1.27 + TypeOpName(kAddScalar), 1.28 + TypeOpName(kAddString), // string concat 1.29 + TypeOpName(kArrayIndex), 1.30 + TypeOpName(kArrayParam), 1.31 + TypeOpName(kArrayToken), 1.32 + TypeOpName(kBitAndInt), 1.33 + TypeOpName(kBitNotInt), 1.34 + TypeOpName(kBitOrInt), 1.35 + TypeOpName(kBoxToken), 1.36 + TypeOpName(kCallback), 1.37 + TypeOpName(kDivideInt), 1.38 + TypeOpName(kDivideScalar), 1.39 + TypeOpName(kDotOperator), 1.40 + TypeOpName(kElseOp), 1.41 + TypeOpName(kEnd), 1.42 + TypeOpName(kEqualInt), 1.43 + TypeOpName(kEqualScalar), 1.44 + TypeOpName(kEqualString), 1.45 + TypeOpName(kFunctionCall), 1.46 + TypeOpName(kFlipOpsOp), 1.47 + TypeOpName(kFunctionToken), 1.48 + TypeOpName(kGreaterEqualInt), 1.49 + TypeOpName(kGreaterEqualScalar), 1.50 + TypeOpName(kGreaterEqualString), 1.51 + TypeOpName(kIfOp), 1.52 + TypeOpName(kIntToScalar), 1.53 + TypeOpName(kIntToScalar2), 1.54 + TypeOpName(kIntToString), 1.55 + TypeOpName(kIntToString2), 1.56 + TypeOpName(kIntegerAccumulator), 1.57 + TypeOpName(kIntegerOperand), 1.58 + TypeOpName(kLogicalAndInt), 1.59 + TypeOpName(kLogicalNotInt), 1.60 + TypeOpName(kLogicalOrInt), 1.61 + TypeOpName(kMemberOp), 1.62 + TypeOpName(kMinusInt), 1.63 + TypeOpName(kMinusScalar), 1.64 + TypeOpName(kModuloInt), 1.65 + TypeOpName(kModuloScalar), 1.66 + TypeOpName(kMultiplyInt), 1.67 + TypeOpName(kMultiplyScalar), 1.68 + TypeOpName(kPropertyOp), 1.69 + TypeOpName(kScalarAccumulator), 1.70 + TypeOpName(kScalarOperand), 1.71 + TypeOpName(kScalarToInt), 1.72 + TypeOpName(kScalarToInt2), 1.73 + TypeOpName(kScalarToString), 1.74 + TypeOpName(kScalarToString2), 1.75 + TypeOpName(kShiftLeftInt), 1.76 + TypeOpName(kShiftRightInt), // signed 1.77 + TypeOpName(kStringAccumulator), 1.78 + TypeOpName(kStringOperand), 1.79 + TypeOpName(kStringToInt), 1.80 + TypeOpName(kStringToScalar), 1.81 + TypeOpName(kStringToScalar2), 1.82 + TypeOpName(kStringTrack), 1.83 + TypeOpName(kSubtractInt), 1.84 + TypeOpName(kSubtractScalar), 1.85 + TypeOpName(kToBool), 1.86 + TypeOpName(kUnboxToken), 1.87 + TypeOpName(kUnboxToken2), 1.88 + TypeOpName(kXorInt) 1.89 +}; 1.90 + 1.91 +static size_t gOpNamesSize = sizeof(gOpNames) / sizeof(gOpNames[0]); 1.92 + 1.93 +#define OperandName(op) {SkOperand2::op, #op } 1.94 + 1.95 +static const struct OperName { 1.96 + SkOperand2::OpType fType; 1.97 + const char* fName; 1.98 +} gOperandNames[] = { 1.99 + OperandName(kNoType), 1.100 + OperandName(kS32), 1.101 + OperandName(kScalar), 1.102 + OperandName(kString), 1.103 + OperandName(kArray), 1.104 + OperandName(kObject) 1.105 +}; 1.106 + 1.107 +static size_t gOperandNamesSize = sizeof(gOperandNames) / sizeof(gOperandNames[0]); 1.108 + 1.109 +// check to see that there are no missing or duplicate entries 1.110 +void SkScriptEngine2::ValidateDecompileTable() { 1.111 + SkScriptEngine2::TypeOp op = SkScriptEngine2::kNop; 1.112 + size_t index; 1.113 + for (index = 0; index < gOpNamesSize; index++) { 1.114 + SkASSERT(gOpNames[index].fOp == op); 1.115 + op = (SkScriptEngine2::TypeOp) (op + 1); 1.116 + } 1.117 + index = 0; 1.118 + SkOperand2::OpType type = SkOperand2::kNoType; 1.119 + SkASSERT(gOperandNames[index].fType == type); 1.120 + for (; index < gOperandNamesSize - 1; ) { 1.121 + type = (SkOperand2::OpType) (1 << index); 1.122 + SkASSERT(gOperandNames[++index].fType == type); 1.123 + } 1.124 +} 1.125 + 1.126 +void SkScriptEngine2::decompile(const unsigned char* start, size_t length) { 1.127 + SkASSERT(length > 0); 1.128 + const unsigned char* opCode = start; 1.129 + do { 1.130 + SkASSERT((size_t)(opCode - start) < length); 1.131 + SkScriptEngine2::TypeOp op = (SkScriptEngine2::TypeOp) *opCode++; 1.132 + SkASSERT((size_t)op < gOpNamesSize); 1.133 + SkDebugf("%d: %s", opCode - start - 1, gOpNames[op].fName); 1.134 + switch (op) { 1.135 + case SkScriptEngine2::kCallback: { 1.136 + int index; 1.137 + memcpy(&index, opCode, sizeof(index)); 1.138 + opCode += sizeof(index); 1.139 + SkDebugf(" index: %d", index); 1.140 + } break; 1.141 + case SkScriptEngine2::kFunctionCall: 1.142 + case SkScriptEngine2::kMemberOp: 1.143 + case SkScriptEngine2::kPropertyOp: { 1.144 + size_t ref; 1.145 + memcpy(&ref, opCode, sizeof(ref)); 1.146 + opCode += sizeof(ref); 1.147 + SkDebugf(" ref: %d", ref); 1.148 + } break; 1.149 + case SkScriptEngine2::kIntegerAccumulator: 1.150 + case SkScriptEngine2::kIntegerOperand: { 1.151 + int32_t integer; 1.152 + memcpy(&integer, opCode, sizeof(integer)); 1.153 + opCode += sizeof(int32_t); 1.154 + SkDebugf(" integer: %d", integer); 1.155 + } break; 1.156 + case SkScriptEngine2::kScalarAccumulator: 1.157 + case SkScriptEngine2::kScalarOperand: { 1.158 + SkScalar scalar; 1.159 + memcpy(&scalar, opCode, sizeof(scalar)); 1.160 + opCode += sizeof(SkScalar); 1.161 + SkDebugf(" scalar: %g", SkScalarToFloat(scalar)); 1.162 + } break; 1.163 + case SkScriptEngine2::kStringAccumulator: 1.164 + case SkScriptEngine2::kStringOperand: { 1.165 + int size; 1.166 + SkString* strPtr = new SkString(); 1.167 + memcpy(&size, opCode, sizeof(size)); 1.168 + opCode += sizeof(size); 1.169 + strPtr->set((char*) opCode, size); 1.170 + opCode += size; 1.171 + SkDebugf(" string: %s", strPtr->c_str()); 1.172 + delete strPtr; 1.173 + } break; 1.174 + case SkScriptEngine2::kBoxToken: { 1.175 + SkOperand2::OpType type; 1.176 + memcpy(&type, opCode, sizeof(type)); 1.177 + opCode += sizeof(type); 1.178 + size_t index = 0; 1.179 + if (type == 0) 1.180 + SkDebugf(" type: %s", gOperandNames[index].fName); 1.181 + else { 1.182 + while (type != 0) { 1.183 + SkASSERT(index + 1 < gOperandNamesSize); 1.184 + if (type & (1 << index)) { 1.185 + type = (SkOperand2::OpType) (type & ~(1 << index)); 1.186 + SkDebugf(" type: %s", gOperandNames[index + 1].fName); 1.187 + } 1.188 + index++; 1.189 + } 1.190 + } 1.191 + } break; 1.192 + case SkScriptEngine2::kIfOp: 1.193 + case SkScriptEngine2::kLogicalAndInt: 1.194 + case SkScriptEngine2::kElseOp: 1.195 + case SkScriptEngine2::kLogicalOrInt: { 1.196 + int size; 1.197 + memcpy(&size, opCode, sizeof(size)); 1.198 + opCode += sizeof(size); 1.199 + SkDebugf(" offset (address): %d (%d)", size, opCode - start + size); 1.200 + } break; 1.201 + case SkScriptEngine2::kEnd: 1.202 + goto done; 1.203 + case SkScriptEngine2::kNop: 1.204 + SkASSERT(0); 1.205 + default: 1.206 + break; 1.207 + } 1.208 + SkDebugf("\n"); 1.209 + } while (true); 1.210 +done: 1.211 + SkDebugf("\n"); 1.212 +} 1.213 + 1.214 +#endif