1 2 /* 3 * Copyright 2006 The Android Open Source Project 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10 #include "SkScript2.h" 11 12 #ifdef SK_DEBUG 13 14 #define TypeOpName(op) {SkScriptEngine2::op, #op } 15 16 static const struct OpName { 17 SkScriptEngine2::TypeOp fOp; 18 const char* fName; 19 } gOpNames[] = { 20 TypeOpName(kNop), // should never get generated 21 TypeOpName(kAccumulatorPop), 22 TypeOpName(kAccumulatorPush), 23 TypeOpName(kAddInt), 24 TypeOpName(kAddScalar), 25 TypeOpName(kAddString), // string concat 26 TypeOpName(kArrayIndex), 27 TypeOpName(kArrayParam), 28 TypeOpName(kArrayToken), 29 TypeOpName(kBitAndInt), 30 TypeOpName(kBitNotInt), 31 TypeOpName(kBitOrInt), 32 TypeOpName(kBoxToken), 33 TypeOpName(kCallback), 34 TypeOpName(kDivideInt), 35 TypeOpName(kDivideScalar), 36 TypeOpName(kDotOperator), 37 TypeOpName(kElseOp), 38 TypeOpName(kEnd), 39 TypeOpName(kEqualInt), 40 TypeOpName(kEqualScalar), 41 TypeOpName(kEqualString), 42 TypeOpName(kFunctionCall), 43 TypeOpName(kFlipOpsOp), 44 TypeOpName(kFunctionToken), 45 TypeOpName(kGreaterEqualInt), 46 TypeOpName(kGreaterEqualScalar), 47 TypeOpName(kGreaterEqualString), 48 TypeOpName(kIfOp), 49 TypeOpName(kIntToScalar), 50 TypeOpName(kIntToScalar2), 51 TypeOpName(kIntToString), 52 TypeOpName(kIntToString2), 53 TypeOpName(kIntegerAccumulator), 54 TypeOpName(kIntegerOperand), 55 TypeOpName(kLogicalAndInt), 56 TypeOpName(kLogicalNotInt), 57 TypeOpName(kLogicalOrInt), 58 TypeOpName(kMemberOp), 59 TypeOpName(kMinusInt), 60 TypeOpName(kMinusScalar), 61 TypeOpName(kModuloInt), 62 TypeOpName(kModuloScalar), 63 TypeOpName(kMultiplyInt), 64 TypeOpName(kMultiplyScalar), 65 TypeOpName(kPropertyOp), 66 TypeOpName(kScalarAccumulator), 67 TypeOpName(kScalarOperand), 68 TypeOpName(kScalarToInt), 69 TypeOpName(kScalarToInt2), 70 TypeOpName(kScalarToString), 71 TypeOpName(kScalarToString2), 72 TypeOpName(kShiftLeftInt), 73 TypeOpName(kShiftRightInt), // signed 74 TypeOpName(kStringAccumulator), 75 TypeOpName(kStringOperand), 76 TypeOpName(kStringToInt), 77 TypeOpName(kStringToScalar), 78 TypeOpName(kStringToScalar2), 79 TypeOpName(kStringTrack), 80 TypeOpName(kSubtractInt), 81 TypeOpName(kSubtractScalar), 82 TypeOpName(kToBool), 83 TypeOpName(kUnboxToken), 84 TypeOpName(kUnboxToken2), 85 TypeOpName(kXorInt) 86 }; 87 88 static size_t gOpNamesSize = sizeof(gOpNames) / sizeof(gOpNames[0]); 89 90 #define OperandName(op) {SkOperand2::op, #op } 91 92 static const struct OperName { 93 SkOperand2::OpType fType; 94 const char* fName; 95 } gOperandNames[] = { 96 OperandName(kNoType), 97 OperandName(kS32), 98 OperandName(kScalar), 99 OperandName(kString), 100 OperandName(kArray), 101 OperandName(kObject) 102 }; 103 104 static size_t gOperandNamesSize = sizeof(gOperandNames) / sizeof(gOperandNames[0]); 105 106 // check to see that there are no missing or duplicate entries 107 void SkScriptEngine2::ValidateDecompileTable() { 108 SkScriptEngine2::TypeOp op = SkScriptEngine2::kNop; 109 size_t index; 110 for (index = 0; index < gOpNamesSize; index++) { 111 SkASSERT(gOpNames[index].fOp == op); 112 op = (SkScriptEngine2::TypeOp) (op + 1); 113 } 114 index = 0; 115 SkOperand2::OpType type = SkOperand2::kNoType; 116 SkASSERT(gOperandNames[index].fType == type); 117 for (; index < gOperandNamesSize - 1; ) { 118 type = (SkOperand2::OpType) (1 << index); 119 SkASSERT(gOperandNames[++index].fType == type); 120 } 121 } 122 123 void SkScriptEngine2::decompile(const unsigned char* start, size_t length) { 124 SkASSERT(length > 0); 125 const unsigned char* opCode = start; 126 do { 127 SkASSERT((size_t)(opCode - start) < length); 128 SkScriptEngine2::TypeOp op = (SkScriptEngine2::TypeOp) *opCode++; 129 SkASSERT((size_t)op < gOpNamesSize); 130 SkDebugf("%d: %s", opCode - start - 1, gOpNames[op].fName); 131 switch (op) { 132 case SkScriptEngine2::kCallback: { 133 int index; 134 memcpy(&index, opCode, sizeof(index)); 135 opCode += sizeof(index); 136 SkDebugf(" index: %d", index); 137 } break; 138 case SkScriptEngine2::kFunctionCall: 139 case SkScriptEngine2::kMemberOp: 140 case SkScriptEngine2::kPropertyOp: { 141 size_t ref; 142 memcpy(&ref, opCode, sizeof(ref)); 143 opCode += sizeof(ref); 144 SkDebugf(" ref: %d", ref); 145 } break; 146 case SkScriptEngine2::kIntegerAccumulator: 147 case SkScriptEngine2::kIntegerOperand: { 148 int32_t integer; 149 memcpy(&integer, opCode, sizeof(integer)); 150 opCode += sizeof(int32_t); 151 SkDebugf(" integer: %d", integer); 152 } break; 153 case SkScriptEngine2::kScalarAccumulator: 154 case SkScriptEngine2::kScalarOperand: { 155 SkScalar scalar; 156 memcpy(&scalar, opCode, sizeof(scalar)); 157 opCode += sizeof(SkScalar); 158 #ifdef SK_CAN_USE_FLOAT 159 SkDebugf(" scalar: %g", SkScalarToFloat(scalar)); 160 #else 161 SkDebugf(" scalar: %x", scalar); 162 #endif 163 } break; 164 case SkScriptEngine2::kStringAccumulator: 165 case SkScriptEngine2::kStringOperand: { 166 int size; 167 SkString* strPtr = new SkString(); 168 memcpy(&size, opCode, sizeof(size)); 169 opCode += sizeof(size); 170 strPtr->set((char*) opCode, size); 171 opCode += size; 172 SkDebugf(" string: %s", strPtr->c_str()); 173 delete strPtr; 174 } break; 175 case SkScriptEngine2::kBoxToken: { 176 SkOperand2::OpType type; 177 memcpy(&type, opCode, sizeof(type)); 178 opCode += sizeof(type); 179 size_t index = 0; 180 if (type == 0) 181 SkDebugf(" type: %s", gOperandNames[index].fName); 182 else { 183 while (type != 0) { 184 SkASSERT(index + 1 < gOperandNamesSize); 185 if (type & (1 << index)) { 186 type = (SkOperand2::OpType) (type & ~(1 << index)); 187 SkDebugf(" type: %s", gOperandNames[index + 1].fName); 188 } 189 index++; 190 } 191 } 192 } break; 193 case SkScriptEngine2::kIfOp: 194 case SkScriptEngine2::kLogicalAndInt: 195 case SkScriptEngine2::kElseOp: 196 case SkScriptEngine2::kLogicalOrInt: { 197 int size; 198 memcpy(&size, opCode, sizeof(size)); 199 opCode += sizeof(size); 200 SkDebugf(" offset (address): %d (%d)", size, opCode - start + size); 201 } break; 202 case SkScriptEngine2::kEnd: 203 goto done; 204 case SkScriptEngine2::kNop: 205 SkASSERT(0); 206 default: 207 break; 208 } 209 SkDebugf("\n"); 210 } while (true); 211 done: 212 SkDebugf("\n"); 213 } 214 215 #endif 216