blob: 995da874cbf169d00d1dabcf34330d95f84d4f96 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
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
reed@android.com8a1c16f2008-12-17 15:59:43 +00009
10#include "SkScript2.h"
11
12#ifdef SK_DEBUG
13
14#define TypeOpName(op) {SkScriptEngine2::op, #op }
15
16static 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
88static size_t gOpNamesSize = sizeof(gOpNames) / sizeof(gOpNames[0]);
89
90#define OperandName(op) {SkOperand2::op, #op }
91
92static 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)
rmistry@google.comd6176b02012-08-23 18:14:13 +0000102};
reed@android.com8a1c16f2008-12-17 15:59:43 +0000103
104static size_t gOperandNamesSize = sizeof(gOperandNames) / sizeof(gOperandNames[0]);
105
106// check to see that there are no missing or duplicate entries
107void SkScriptEngine2::ValidateDecompileTable() {
108 SkScriptEngine2::TypeOp op = SkScriptEngine2::kNop;
senorblanco@chromium.org64cc5792011-05-19 19:58:58 +0000109 size_t index;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000110 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
123void SkScriptEngine2::decompile(const unsigned char* start, size_t length) {
124 SkASSERT(length > 0);
125 const unsigned char* opCode = start;
126 do {
senorblanco@chromium.org64cc5792011-05-19 19:58:58 +0000127 SkASSERT((size_t)(opCode - start) < length);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000128 SkScriptEngine2::TypeOp op = (SkScriptEngine2::TypeOp) *opCode++;
senorblanco@chromium.org64cc5792011-05-19 19:58:58 +0000129 SkASSERT((size_t)op < gOpNamesSize);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000130 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;
rmistry@google.comd6176b02012-08-23 18:14:13 +0000138 case SkScriptEngine2::kFunctionCall:
reed@android.com8a1c16f2008-12-17 15:59:43 +0000139 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);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000158 SkDebugf(" scalar: %g", SkScalarToFloat(scalar));
reed@android.com8a1c16f2008-12-17 15:59:43 +0000159 } 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);
senorblanco@chromium.org64cc5792011-05-19 19:58:58 +0000175 size_t index = 0;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000176 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);
senorblanco@chromium.org64cc5792011-05-19 19:58:58 +0000202 default:
203 break;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000204 }
205 SkDebugf("\n");
206 } while (true);
207done:
208 SkDebugf("\n");
209}
210
211#endif