Home | History | Annotate | Download | only in animator
      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