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
ValidateDecompileTable()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
decompile(const unsigned char * start,size_t length)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 SkDebugf(" scalar: %g", SkScalarToFloat(scalar));
159 } break;
160 case SkScriptEngine2::kStringAccumulator:
161 case SkScriptEngine2::kStringOperand: {
162 int size;
163 SkString* strPtr = new SkString();
164 memcpy(&size, opCode, sizeof(size));
165 opCode += sizeof(size);
166 strPtr->set((char*) opCode, size);
167 opCode += size;
168 SkDebugf(" string: %s", strPtr->c_str());
169 delete strPtr;
170 } break;
171 case SkScriptEngine2::kBoxToken: {
172 SkOperand2::OpType type;
173 memcpy(&type, opCode, sizeof(type));
174 opCode += sizeof(type);
175 size_t index = 0;
176 if (type == 0)
177 SkDebugf(" type: %s", gOperandNames[index].fName);
178 else {
179 while (type != 0) {
180 SkASSERT(index + 1 < gOperandNamesSize);
181 if (type & (1 << index)) {
182 type = (SkOperand2::OpType) (type & ~(1 << index));
183 SkDebugf(" type: %s", gOperandNames[index + 1].fName);
184 }
185 index++;
186 }
187 }
188 } break;
189 case SkScriptEngine2::kIfOp:
190 case SkScriptEngine2::kLogicalAndInt:
191 case SkScriptEngine2::kElseOp:
192 case SkScriptEngine2::kLogicalOrInt: {
193 int size;
194 memcpy(&size, opCode, sizeof(size));
195 opCode += sizeof(size);
196 SkDebugf(" offset (address): %d (%d)", size, opCode - start + size);
197 } break;
198 case SkScriptEngine2::kEnd:
199 goto done;
200 case SkScriptEngine2::kNop:
201 SkASSERT(0);
202 default:
203 break;
204 }
205 SkDebugf("\n");
206 } while (true);
207 done:
208 SkDebugf("\n");
209 }
210
211 #endif
212