10910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkScript2.h"
20910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkFloatingPoint.h"
30910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkMath.h"
40910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkParse.h"
50910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkScriptCallBack.h"
60910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkScriptRuntime.h"
70910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkString.h"
80910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkOpArray.h"
90910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectconst SkScriptEngine2::OperatorAttributes SkScriptEngine2::gOpAttributes[] = {
110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger{ SkOperand2::kNoType, SkOperand2::kNoType, kNoBias, kResultIsNotBoolean },
120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ SkOperand2::OpType(SkOperand2::kS32 | SkOperand2::kScalar | SkOperand2::kString),
130b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkOperand2::OpType(SkOperand2::kS32 | SkOperand2::kScalar | SkOperand2::kString), kTowardsString, kResultIsNotBoolean },    // kAdd
140b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger{ SkOperand2::kS32, SkOperand2::kS32, kNoBias, kResultIsNotBoolean }, // kBitAnd
150b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger{ SkOperand2::kNoType, SkOperand2::kS32, kNoBias, kResultIsNotBoolean }, // kBitNot
160b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger{ SkOperand2::kS32, SkOperand2::kS32, kNoBias, kResultIsNotBoolean }, // kBitOr
170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ SkOperand2::OpType(SkOperand2::kS32 | SkOperand2::kScalar),
180b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkOperand2::OpType(SkOperand2::kS32 | SkOperand2::kScalar), kNoBias, kResultIsNotBoolean }, // kDivide
190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ SkOperand2::OpType(SkOperand2::kS32 | SkOperand2::kScalar | SkOperand2::kString),
200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkOperand2::OpType(SkOperand2::kS32 | SkOperand2::kScalar |SkOperand2:: kString), kTowardsNumber,
210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    kResultIsBoolean }, // kEqual
220b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger{ SkOperand2::kS32, SkOperand2::kNoType, kNoBias, kResultIsNotBoolean },     // kFlipOps
230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ SkOperand2::OpType(SkOperand2::kS32 | SkOperand2::kScalar | SkOperand2::kString),
240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkOperand2::OpType(SkOperand2::kS32 | SkOperand2::kScalar | SkOperand2::kString), kTowardsNumber,
250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    kResultIsBoolean }, // kGreaterEqual
260b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger{ SkOperand2::kNoType, SkOperand2::kS32, kNoBias, kResultIsNotBoolean }, // kLogicalAnd    (really, ToBool)
270b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger{ SkOperand2::kNoType, SkOperand2::kS32, kNoBias, kResultIsNotBoolean }, // kLogicalNot
280b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger{ SkOperand2::kS32, SkOperand2::kS32, kNoBias, kResultIsNotBoolean }, // kLogicalOr
290b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger{ SkOperand2::kNoType, SkOperand2::OpType(SkOperand2::kS32 | SkOperand2::kScalar), kNoBias, kResultIsNotBoolean }, // kMinus
300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ SkOperand2::OpType(SkOperand2::kS32 | SkOperand2::kScalar),
310b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkOperand2::OpType(SkOperand2::kS32 |SkOperand2:: kScalar), kNoBias, kResultIsNotBoolean }, // kModulo
320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ SkOperand2::OpType(SkOperand2::kS32 | SkOperand2::kScalar),
330b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkOperand2::OpType(SkOperand2::kS32 | SkOperand2::kScalar), kNoBias, kResultIsNotBoolean }, // kMultiply
340b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger{ SkOperand2::kS32, SkOperand2::kS32, kNoBias, kResultIsNotBoolean }, // kShiftLeft
350b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger{ SkOperand2::kS32, SkOperand2::kS32, kNoBias, kResultIsNotBoolean }, // kShiftRight
360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{ SkOperand2::OpType(SkOperand2::kS32 | SkOperand2::kScalar),
370b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkOperand2::OpType(SkOperand2::kS32 | SkOperand2::kScalar), kNoBias, kResultIsNotBoolean }, // kSubtract
380b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger{ SkOperand2::kS32, SkOperand2::kS32, kNoBias, kResultIsNotBoolean } // kXor
390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define kBracketPrecedence 16
420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define kIfElsePrecedence 15
430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectconst signed char SkScriptEngine2::gPrecedence[] = {
450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    17, // kUnassigned,
460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    6, // kAdd,
470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    10, // kBitAnd,
480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    4, // kBitNot,
490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    12, // kBitOr,
500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    5, // kDivide,
510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    9, // kEqual,
520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    -1, // kFlipOps,
530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    8, // kGreaterEqual,
540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    13, // kLogicalAnd,
550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    4, // kLogicalNot,
560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    14, // kLogicalOr,
570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    4, // kMinus,
580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    5, // kModulo,
590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    5, // kMultiply,
600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    7, // kShiftLeft,
610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    7, // kShiftRight,    // signed
620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    6, // kSubtract,
630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    11, // kXor
640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    kBracketPrecedence, // kArrayOp
650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    kIfElsePrecedence, // kElse
660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    kIfElsePrecedence, // kIf
670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    kBracketPrecedence, // kParen
680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectconst SkScriptEngine2::TypeOp SkScriptEngine2::gTokens[] = {
710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    kNop, // unassigned
720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    kAddInt, // kAdd,
730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    kBitAndInt, // kBitAnd,
740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    kBitNotInt, // kBitNot,
750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    kBitOrInt, // kBitOr,
760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    kDivideInt, // kDivide,
770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    kEqualInt, // kEqual,
780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    kFlipOpsOp, // kFlipOps,
790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    kGreaterEqualInt, // kGreaterEqual,
800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    kLogicalAndInt, // kLogicalAnd,
810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    kLogicalNotInt, // kLogicalNot,
820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    kLogicalOrInt, // kLogicalOr,
830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    kMinusInt, // kMinus,
840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    kModuloInt, // kModulo,
850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    kMultiplyInt, // kMultiply,
860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    kShiftLeftInt, // kShiftLeft,
870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    kShiftRightInt, // kShiftRight,    // signed
880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    kSubtractInt, // kSubtract,
890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    kXorInt // kXor
900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline bool is_between(int c, int min, int max)
930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return (unsigned)(c - min) <= (unsigned)(max - min);
950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic inline bool is_ws(int c)
980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return is_between(c, 1, 32);
1000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic int token_length(const char* start) {
1030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    char ch = start[0];
1040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (! is_between(ch, 'a' , 'z') &&  ! is_between(ch, 'A', 'Z') && ch != '_' && ch != '$')
1050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return -1;
1060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int length = 0;
1070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    do
1080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        ch = start[++length];
1090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (is_between(ch, 'a' , 'z') || is_between(ch, 'A', 'Z') || is_between(ch, '0', '9') ||
1100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project           ch == '_' || ch == '$');
1110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return length;
1120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkScriptEngine2::SkScriptEngine2(SkOperand2::OpType returnType) : fActiveStream(&fStream),
1150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectfTokenLength(0), fReturnType(returnType), fError(kNoError),
1160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectfAccumulatorType(SkOperand2::kNoType),
1170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectfBranchPopAllowed(true), fConstExpression(true), fOperandInUse(false)
1180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project{
1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Branch branch(kUnassigned, 0, 0);
1200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fBranchStack.push(branch);
1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *fOpStack.push() = (Op) kParen;
1220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkScriptEngine2::~SkScriptEngine2() {
1250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    for (SkString** stringPtr = fTrackString.begin(); stringPtr < fTrackString.end(); stringPtr++)
1260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        delete *stringPtr;
1270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    for (SkOpArray** arrayPtr = fTrackArray.begin(); arrayPtr < fTrackArray.end(); arrayPtr++)
1280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        delete *arrayPtr;
1290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkScriptEngine2::addToken(SkScriptEngine2::TypeOp op) {
1320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int limit = fBranchStack.count() - 1;
1330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    for (int index = 0; index < limit; index++) {
1340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Branch& branch = fBranchStack.index(index);
1350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (branch.fPrimed == Branch::kIsPrimed)
1360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            resolveBranch(branch);
1370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fBranchPopAllowed) {
1390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        while (fBranchStack.top().fDone == Branch::kIsDone)
1400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fBranchStack.pop();
1410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    unsigned char charOp = (unsigned char) op;
1430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fActiveStream->write(&charOp, sizeof(charOp));
1440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkScriptEngine2::addTokenConst(SkScriptValue2* value, AddTokenRegister reg,
1470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                    SkOperand2::OpType toType, SkScriptEngine2::TypeOp op) {
1480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (value->fIsConstant == SkScriptValue2::kConstant && convertTo(toType, value))
1490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return;
1500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    addTokenValue(*value, reg);
1510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    addToken(op);
1520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    value->fIsWritten = SkScriptValue2::kWritten;
1530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    value->fType = toType;
1540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkScriptEngine2::addTokenInt(int integer) {
1570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fActiveStream->write(&integer, sizeof(integer));
1580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkScriptEngine2::addTokenScalar(SkScalar scalar) {
1610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fActiveStream->write(&scalar, sizeof(scalar));
1620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkScriptEngine2::addTokenString(const SkString& string) {
1650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int size = string.size();
1660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    addTokenInt(size);
1670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fActiveStream->write(string.c_str(), size);
1680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
1690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkScriptEngine2::addTokenValue(const SkScriptValue2& value, AddTokenRegister reg) {
1710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (value.isConstant() == false) {
1720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (reg == kAccumulator) {
1730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (fAccumulatorType == SkOperand2::kNoType)
1740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                addToken(kAccumulatorPop);
1750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } else {
1760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            ; // !!! incomplete?
1770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
1780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return;
1790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
1800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (reg == kAccumulator && fAccumulatorType != SkOperand2::kNoType)
1810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        addToken(kAccumulatorPush);
1820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    switch (value.fType) {
1830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkOperand2::kS32:
1840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            addToken(reg == kAccumulator ? kIntegerAccumulator : kIntegerOperand);
1850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            addTokenInt(value.fOperand.fS32);
1860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (reg == kAccumulator)
1870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                fAccumulatorType = SkOperand2::kS32;
1880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            else
1890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                fOperandInUse = true;
1900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
1910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkOperand2::kScalar:
1920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            addToken(reg == kAccumulator ? kScalarAccumulator : kScalarOperand);
1930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            addTokenScalar(value.fOperand.fScalar);
1940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (reg == kAccumulator)
1950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                fAccumulatorType = SkOperand2::kScalar;
1960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            else
1970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                fOperandInUse = true;
1980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
1990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkOperand2::kString:
2000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            addToken(reg == kAccumulator ? kStringAccumulator : kStringOperand);
2010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            addTokenString(*value.fOperand.fString);
2020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (reg == kAccumulator)
2030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                fAccumulatorType = SkOperand2::kString;
2040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            else
2050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                fOperandInUse = true;
2060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
2070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        default:
2080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(0); //!!! not implemented yet
2090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
2110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
2120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectint SkScriptEngine2::arithmeticOp(char ch, char nextChar, bool lastPush) {
2130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Op op = kUnassigned;
2140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool reverseOperands = false;
2150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool negateResult = false;
2160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int advance = 1;
2170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    switch (ch) {
2180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case '+':
2190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            // !!! ignoring unary plus as implemented here has the side effect of
2200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            // suppressing errors like +"hi"
2210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (lastPush == false)    // unary plus, don't push an operator
2224c1d4eb4c9602adf6207d1dffcbfc793cffc43e8Mike Reed                return advance;
2230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            op = kAdd;
2240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
2250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case '-':
2260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            op = lastPush ? kSubtract : kMinus;
2270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
2280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case '*':
2290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            op = kMultiply;
2300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
2310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case '/':
2320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            op = kDivide;
2330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
2340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case '>':
2350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (nextChar == '>') {
2360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                op = kShiftRight;
2370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                goto twoChar;
2380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
2390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            op = kGreaterEqual;
2400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (nextChar == '=')
2410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                goto twoChar;
2420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                reverseOperands = negateResult = true;
2430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
2440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case '<':
2450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (nextChar == '<') {
2460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                op = kShiftLeft;
2470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                goto twoChar;
2480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
2490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            op = kGreaterEqual;
2500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            reverseOperands = nextChar == '=';
2510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            negateResult = ! reverseOperands;
2520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            advance += reverseOperands;
2530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
2540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case '=':
2550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (nextChar == '=') {
2560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                op = kEqual;
2570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                goto twoChar;
2580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
2590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
2600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case '!':
2610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (nextChar == '=') {
2620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                op = kEqual;
2630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                negateResult = true;
2640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjecttwoChar:
2650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    advance++;
2660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                break;
2670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
2680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            op = kLogicalNot;
2690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
2700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case '?':
2710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            op =(Op)  kIf;
2720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
2730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case ':':
2740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            op = (Op) kElse;
2750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
2760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case '^':
2770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            op = kXor;
2780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
2790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case '(':
2800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            *fOpStack.push() = (Op) kParen;
2814c1d4eb4c9602adf6207d1dffcbfc793cffc43e8Mike Reed            return advance;
2820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case '&':
2830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(nextChar != '&');
2840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            op = kBitAnd;
2850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
2860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case '|':
2870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(nextChar != '|');
2880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            op = kBitOr;
2890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
2900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case '%':
2910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            op = kModulo;
2920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
2930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case '~':
2940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            op = kBitNot;
2950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
2960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
2970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (op == kUnassigned)
2980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return 0;
2990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    signed char precedence = gPrecedence[op];
3000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    do {
3010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int idx = 0;
3020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Op compare;
3030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        do {
3040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            compare = fOpStack.index(idx);
3050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if ((compare & kArtificialOp) == 0)
3060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                break;
3070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            idx++;
3080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } while (true);
3090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        signed char topPrecedence = gPrecedence[compare];
3100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(topPrecedence != -1);
3110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger        if (topPrecedence > precedence || (topPrecedence == precedence &&
3120b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger            gOpAttributes[op].fLeftType == SkOperand2::kNoType)) {
3130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
3140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
3150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        processOp();
3160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } while (true);
3170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (negateResult)
3180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *fOpStack.push() = (Op) (kLogicalNot | kArtificialOp);
3190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fOpStack.push(op);
3200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (reverseOperands)
3210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *fOpStack.push() = (Op) (kFlipOps | kArtificialOp);
3224c1d4eb4c9602adf6207d1dffcbfc793cffc43e8Mike Reed
3234c1d4eb4c9602adf6207d1dffcbfc793cffc43e8Mike Reed    return advance;
3240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkScriptEngine2::convertParams(SkTDArray<SkScriptValue2>* params,
3270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                    const SkOperand2::OpType* paramTypes, int paramCount) {
3280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int count = params->count();
3290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (count > paramCount) {
3300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(0);
3310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return false;    // too many parameters passed
3320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
3330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    for (int index = 0; index < count; index++)
3340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        convertTo(paramTypes[index], &(*params)[index]);
3350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return true;
3360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkScriptEngine2::convertTo(SkOperand2::OpType toType, SkScriptValue2* value ) {
3390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkOperand2::OpType type = value->fType;
3400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (type == toType)
3410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return true;
3420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (type == SkOperand2::kObject) {
3430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (handleUnbox(value) == false)
3440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return false;
3450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return convertTo(toType, value);
3460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
3470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return ConvertTo(this, toType, value);
3480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkScriptEngine2::evaluateDot(const char*& script) {
3510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    size_t fieldLength = token_length(++script);        // skip dot
3520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(fieldLength > 0); // !!! add error handling
3530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* field = script;
3540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    script += fieldLength;
3550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool success = handleProperty();
3560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (success == false) {
3570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fError = kCouldNotFindReferencedID;
3580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        goto error;
3590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
3600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return evaluateDotParam(script, field, fieldLength);
3610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projecterror:
3620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return false;
3630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkScriptEngine2::evaluateDotParam(const char*& script, const char* field, size_t fieldLength) {
3660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScriptValue2& top = fValueStack.top();
3670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (top.fType != SkOperand2::kObject)
3680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return false;
3690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    void* object = top.fOperand.fObject;
3700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fValueStack.pop();
3710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    char ch; // see if it is a simple member or a function
3720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (is_ws(ch = script[0]))
3730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        script++;
3740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool success = true;
3750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (ch != '(')
3760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        success = handleMember(field, fieldLength, object);
3770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else {
3780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkTDArray<SkScriptValue2> params;
3790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *fBraceStack.push() = kFunctionBrace;
3800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        success = functionParams(&script, &params);
3810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (success)
3820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            success = handleMemberFunction(field, fieldLength, object, &params);
3830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
3840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return success;
3850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
3860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
3870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkScriptEngine2::evaluateScript(const char** scriptPtr, SkScriptValue2* value) {
3880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    //    fArrayOffset = 0;        // no support for structures for now
3890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool success;
3900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* inner;
3910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (strncmp(*scriptPtr, "#script:", sizeof("#script:") - 1) == 0) {
3920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *scriptPtr += sizeof("#script:") - 1;
3930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (fReturnType == SkOperand2::kNoType || fReturnType == SkOperand2::kString) {
3940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            success = innerScript(scriptPtr, value);
3950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(success);
3960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            inner = value->fOperand.fString->c_str();
3970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            scriptPtr = &inner;
3980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
3990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    success = innerScript(scriptPtr, value);
4010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* script = *scriptPtr;
4020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    char ch;
4030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (is_ws(ch = script[0]))
4040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        script++;
4050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (ch != '\0') {
4060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        // error may trigger on scripts like "50,0" that were intended to be written as "[50, 0]"
4070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return false;
4080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return success;
4100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkScriptEngine2::forget(SkOpArray* array) {
4130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (array->getType() == SkOperand2::kString) {
4140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        for (int index = 0; index < array->count(); index++) {
4150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkString* string = (*array)[index].fString;
4160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int found = fTrackString.find(string);
4170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (found >= 0)
4180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                fTrackString.remove(found);
4190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
4200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return;
4210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (array->getType() == SkOperand2::kArray) {
4230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        for (int index = 0; index < array->count(); index++) {
4240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkOpArray* child = (*array)[index].fArray;
4250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            forget(child);    // forgets children of child
4260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            int found = fTrackArray.find(child);
4270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (found >= 0)
4280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                fTrackArray.remove(found);
4290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
4300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkScriptEngine2::functionParams(const char** scriptPtr, SkTDArray<SkScriptValue2>* params) {
4340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    (*scriptPtr)++; // skip open paren
4350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *fOpStack.push() = (Op) kParen;
4360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *fBraceStack.push() = kFunctionBrace;
4370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    do {
4380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkScriptValue2 value;
4390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        bool success = innerScript(scriptPtr, &value);
4400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(success);
4410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (success == false)
4420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return false;
4430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        *params->append() = value;
4440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } while ((*scriptPtr)[-1] == ',');
4450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fBraceStack.pop();
4460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fOpStack.pop(); // pop paren
4470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    (*scriptPtr)++; // advance beyond close paren
4480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return true;
4490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectsize_t SkScriptEngine2::getTokenOffset() {
4520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return fActiveStream->getOffset();
4530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkOperand2::OpType SkScriptEngine2::getUnboxType(SkOperand2 scriptValue) {
4560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    for (SkScriptCallBack** callBack = fCallBackArray.begin(); callBack < fCallBackArray.end(); callBack++) {
4570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if ((*callBack)->getType() != SkScriptCallBack::kUnbox)
4580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            continue;
4590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return (*callBack)->getReturnType(0, &scriptValue);
4600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
4610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return SkOperand2::kObject;
4620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
4630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
4640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkScriptEngine2::innerScript(const char** scriptPtr, SkScriptValue2* value) {
4650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* script = *scriptPtr;
4660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    char ch;
4670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool lastPush = false;
4680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool success = true;
4690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int opBalance = fOpStack.count();
4700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int baseBrace = fBraceStack.count();
4710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int branchBalance = fBranchStack.count();
4720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while ((ch = script[0]) != '\0') {
4730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (is_ws(ch)) {
4740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            script++;
4750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            continue;
4760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
4770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkScriptValue2 operand;
4780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const char* dotCheck;
4790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (fBraceStack.count() > baseBrace) {
4800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (fBraceStack.top() == kArrayBrace) {
4810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkScriptValue2 tokenValue;
4820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                success = innerScript(&script, &tokenValue);    // terminate and return on comma, close brace
4830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkASSERT(success);
4840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                {
4850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    SkOperand2::OpType type = fReturnType;
4860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    if (fReturnType == SkOperand2::kNoType) {
4870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        // !!! short sighted; in the future, allow each returned array component to carry
4880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        // its own type, and let caller do any needed conversions
4890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        if (value->fOperand.fArray->count() == 0)
4900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                            value->fOperand.fArray->setType(type = tokenValue.fType);
4910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        else
4920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                            type = value->fOperand.fArray->getType();
4930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    }
4940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    if (tokenValue.fType != type)
4950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                        convertTo(type, &tokenValue);
4960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    *value->fOperand.fArray->append() = tokenValue.fOperand;
4970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
4980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                lastPush = false;
4990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                continue;
5000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            } else
5010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkASSERT(token_length(script) > 0);
5020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
5030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (lastPush != false && fTokenLength > 0) {
5040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (ch == '(') {
5050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *fBraceStack.push() = kFunctionBrace;
5060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkString functionName(fToken, fTokenLength);
5070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
5080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (handleFunction(&script) == false)
5090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    return false;
5100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                lastPush = true;
5110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                continue;
5120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            } else if (ch == '[') {
5130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (handleProperty() == false) {
5140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    SkASSERT(0);
5150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    return false;
5160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
5170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (handleArrayIndexer(&script) == false)
5180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    return false;
5190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                lastPush = true;
5200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                continue;
5210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            } else if (ch != '.') {
5220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (handleProperty() == false) {
5230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    SkASSERT(0);
5240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    return false;
5250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
5260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                lastPush = true;
5270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                continue;
5280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
5290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
5300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (ch == '0' && (script[1] & ~0x20) == 'X') {
5310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(lastPush == false);
5320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            script += 2;
5330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            script = SkParse::FindHex(script, (uint32_t*) &operand.fOperand.fS32);
5340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(script);
5350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            goto intCommon;
5360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
5370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (lastPush == false && ch == '.')
5380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            goto scalarCommon;
5390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (ch >= '0' && ch <= '9') {
5400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(lastPush == false);
5410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            dotCheck = SkParse::FindS32(script, &operand.fOperand.fS32);
5420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (dotCheck[0] != '.') {
5430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                script = dotCheck;
5440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectintCommon:
5450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                operand.fType = SkOperand2::kS32;
5460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            } else {
5470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectscalarCommon:
5480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                script = SkParse::FindScalar(script, &operand.fOperand.fScalar);
5490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                operand.fType = SkOperand2::kScalar;
5500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
5510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            operand.fIsConstant = SkScriptValue2::kConstant;
5520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fValueStack.push(operand);
5530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            lastPush = true;
5540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            continue;
5550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
5560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int length = token_length(script);
5570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (length > 0) {
5580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(lastPush == false);
5590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fToken = script;
5600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fTokenLength = length;
5610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            script += length;
5620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            lastPush = true;
5630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            continue;
5640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
5650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        char startQuote = ch;
5660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (startQuote == '\'' || startQuote == '\"') {
5670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(lastPush == false);
5680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            operand.fOperand.fString = new SkString();
5690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            ++script;
5700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            const char* stringStart = script;
5710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            do {    // measure string
5720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (script[0] == '\\')
5730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    ++script;
5740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                ++script;
5750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkASSERT(script[0]); // !!! throw an error
5760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            } while (script[0] != startQuote);
5770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            operand.fOperand.fString->set(stringStart, script - stringStart);
5780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            script = stringStart;
5790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            char* stringWrite = operand.fOperand.fString->writable_str();
5800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            do {    // copy string
5810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (script[0] == '\\')
5820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    ++script;
5830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *stringWrite++ = script[0];
5840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                ++script;
5850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkASSERT(script[0]); // !!! throw an error
5860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            } while (script[0] != startQuote);
5870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            ++script;
5880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            track(operand.fOperand.fString);
5890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            operand.fType = SkOperand2::kString;
5900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            operand.fIsConstant = SkScriptValue2::kConstant;
5910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fValueStack.push(operand);
5920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            lastPush = true;
5930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            continue;
5940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
5950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (ch ==  '.') {
5960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (fTokenLength == 0) {
5970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkScriptValue2 scriptValue;
5980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkDEBUGCODE(scriptValue.fOperand.fObject = NULL);
5990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                int tokenLength = token_length(++script);
6000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                const char* token = script;
6010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                script += tokenLength;
6020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkASSERT(fValueStack.count() > 0); // !!! add error handling
6030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkScriptValue2 top;
6040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                fValueStack.pop(&top);
6050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                addTokenInt(top.fType);
6070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                addToken(kBoxToken);
6080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                top.fType = SkOperand2::kObject;
6090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                top.fIsConstant = SkScriptValue2::kVariable;
6100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                fConstExpression = false;
6110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                fValueStack.push(top);
6120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                success = evaluateDotParam(script, token, tokenLength);
6130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkASSERT(success);
6140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                lastPush = true;
6150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                continue;
6160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
6170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            // get next token, and evaluate immediately
6180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            success = evaluateDot(script);
6190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (success == false) {
6200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                //                SkASSERT(0);
6210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                return false;
6220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
6230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            lastPush = true;
6240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            continue;
6250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
6260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (ch == '[') {
6270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (lastPush == false) {
6280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                script++;
6290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *fBraceStack.push() = kArrayBrace;
6300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                operand.fOperand.fArray = value->fOperand.fArray = new SkOpArray(fReturnType);
6310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                track(value->fOperand.fArray);
6320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
6330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                operand.fType = SkOperand2::kArray;
6340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                operand.fIsConstant = SkScriptValue2::kVariable;
6350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                fValueStack.push(operand);
6360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                continue;
6370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
6380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (handleArrayIndexer(&script) == false)
6390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                return false;
6400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            lastPush = true;
6410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            continue;
6420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
6430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#if 0 // structs not supported for now
6440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (ch == '{') {
6450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (lastPush == false) {
6460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                script++;
6470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *fBraceStack.push() = kStructBrace;
6480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                operand.fS32 = 0;
6490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                *fTypeStack.push() = (SkOpType) kStruct;
6500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                fOperandStack.push(operand);
6510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                continue;
6520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
6530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(0); // braces in other contexts aren't supported yet
6540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
6550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
6560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (ch == ')' && fBraceStack.count() > 0) {
6570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            BraceStyle braceStyle = fBraceStack.top();
6580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (braceStyle == kFunctionBrace) {
6590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                fBraceStack.pop();
6600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                break;
6610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
6620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
6630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (ch == ',' || ch == ']') {
6640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (ch != ',') {
6650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                BraceStyle match;
6660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                fBraceStack.pop(&match);
6670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkASSERT(match == kArrayBrace);
6680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
6690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            script++;
6700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            // !!! see if brace or bracket is correct closer
6710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
6720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
6730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        char nextChar = script[1];
6740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        int advance = logicalOp(ch, nextChar);
6750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (advance == 0)
6760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            advance = arithmeticOp(ch, nextChar, lastPush);
6770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (advance == 0) // unknown token
6780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return false;
6790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (advance > 0)
6800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            script += advance;
6810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        lastPush = ch == ']' || ch == ')';
6820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
6830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fTokenLength > 0) {
6840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        success = handleProperty();
6850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(success);
6860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
6870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int branchIndex = 0;
6880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    branchBalance = fBranchStack.count() - branchBalance;
6890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fBranchPopAllowed = false;
6900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (branchIndex < branchBalance) {
6910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Branch& branch = fBranchStack.index(branchIndex++);
6920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (branch.fPrimed == Branch::kIsPrimed)
6930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
6940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Op branchOp = branch.fOperator;
6950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkOperand2::OpType lastType = fValueStack.top().fType;
6960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        addTokenValue(fValueStack.top(), kAccumulator);
6970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fValueStack.pop();
6980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (branchOp == kLogicalAnd || branchOp == kLogicalOr) {
6990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (branch.fOperator == kLogicalAnd)
7000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                branch.prime();
7010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            addToken(kToBool);
7020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } else {
7030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            resolveBranch(branch);
7040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkScriptValue2 operand;
7050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            operand.fType = lastType;
7060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            // !!! note that many branching expressions could be constant
7070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            // today, we always evaluate branches as returning variables
7080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            operand.fIsConstant = SkScriptValue2::kVariable;
7090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fValueStack.push(operand);
7100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
7110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (branch.fDone == Branch::kIsNotDone)
7120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            branch.prime();
7130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fBranchPopAllowed = true;
7150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (fBranchStack.top().fDone == Branch::kIsDone)
7160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fBranchStack.pop();
7170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (fOpStack.count() > opBalance) {     // leave open paren
7180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (processOp() == false)
7190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return false;
7200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkOperand2::OpType topType = fValueStack.count() > 0 ? fValueStack.top().fType : SkOperand2::kNoType;
7220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (topType != fReturnType &&
7230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        topType == SkOperand2::kString && fReturnType != SkOperand2::kNoType) { // if result is a string, give handle property a chance to convert it to the property value
7240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkString* string = fValueStack.top().fOperand.fString;
7250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fToken = string->c_str();
7260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fTokenLength = string->size();
7270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fValueStack.pop();
7280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        success = handleProperty();
7290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (success == false) {    // if it couldn't convert, return string (error?)
7300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkScriptValue2 operand;
7310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            operand.fType = SkOperand2::kString;
7320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            operand.fOperand.fString = string;
7330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            operand.fIsConstant = SkScriptValue2::kVariable;     // !!! ?
7340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fValueStack.push(operand);
7350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
7360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (fStream.getOffset() > 0) {
7380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        addToken(kEnd);
7390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
7400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        decompile((const unsigned char*)fStream.getStream(), fStream.getOffset());
7410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
7420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkScriptRuntime runtime(fCallBackArray);
7430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        runtime.executeTokens((unsigned char*) fStream.getStream());
7440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkScriptValue2 value1;
7450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        runtime.getResult(&value1.fOperand);
7460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        value1.fType = fReturnType;
7470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fValueStack.push(value1);
7480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (value) {
7500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (fValueStack.count() == 0)
7510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return false;
7520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fValueStack.pop(value);
7530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (value->fType != fReturnType && value->fType == SkOperand2::kObject &&
7540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fReturnType != SkOperand2::kNoType)
7550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            convertTo(fReturnType, value);
7560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    //    if (fBranchStack.top().fOpStackDepth > fOpStack.count())
7580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    //        resolveBranch();
7590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *scriptPtr = script;
7600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return true; // no error
7610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkScriptEngine2::handleArrayIndexer(const char** scriptPtr) {
7640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScriptValue2 scriptValue;
7650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    (*scriptPtr)++;
7660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *fOpStack.push() = (Op) kParen;
7670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    *fBraceStack.push() = kArrayBrace;
7680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkOperand2::OpType saveType = fReturnType;
7690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fReturnType = SkOperand2::kS32;
7700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool success = innerScript(scriptPtr, &scriptValue);
7710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fReturnType = saveType;
7720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(success);
7730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    success = convertTo(SkOperand2::kS32, &scriptValue);
7740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(success);
7750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int index = scriptValue.fOperand.fS32;
7760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fValueStack.pop(&scriptValue);
7770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (scriptValue.fType == SkOperand2::kObject) {
7780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        success = handleUnbox(&scriptValue);
7790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(success);
7800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(scriptValue.fType == SkOperand2::kArray);
7810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    scriptValue.fType = scriptValue.fOperand.fArray->getType();
7830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    //    SkASSERT(index >= 0);
7840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if ((unsigned) index >= (unsigned) scriptValue.fOperand.fArray->count()) {
7850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fError = kArrayIndexOutOfBounds;
7860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return false;
7870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
7880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    scriptValue.fOperand = scriptValue.fOperand.fArray->begin()[index];
7890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    scriptValue.fIsConstant = SkScriptValue2::kVariable;
7900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fValueStack.push(scriptValue);
7910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fOpStack.pop(); // pop paren
7920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return success;
7930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
7940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
7950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkScriptEngine2::handleFunction(const char** scriptPtr) {
7960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const char* functionName = fToken;
7970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    size_t functionNameLen = fTokenLength;
7980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fTokenLength = 0;
7990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkTDArray<SkScriptValue2> params;
8000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool success = functionParams(scriptPtr, &params);
8010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (success == false)
8020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        goto done;
8030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {
8040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        for (SkScriptCallBack** callBack = fCallBackArray.begin(); callBack < fCallBackArray.end(); callBack++) {
8050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if ((*callBack)->getType() != SkScriptCallBack::kFunction)
8060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                continue;
8070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkScriptValue2 callbackResult;
8080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            success = (*callBack)->getReference(functionName, functionNameLen, &callbackResult);
8090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (success) {
8100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                callbackResult.fType = (*callBack)->getReturnType(callbackResult.fOperand.fReference, NULL);
8110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                callbackResult.fIsConstant = SkScriptValue2::kVariable;
8120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                fValueStack.push(callbackResult);
8130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                goto done;
8140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
8150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
8160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return false;
8180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectdone:
8190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fOpStack.pop();
8200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return success;
8210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
8220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkScriptEngine2::handleMember(const char* field, size_t len, void* object) {
8240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool success = true;
8250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    for (SkScriptCallBack** callBack = fCallBackArray.begin(); callBack < fCallBackArray.end(); callBack++) {
8260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if ((*callBack)->getType() != SkScriptCallBack::kMember)
8270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            continue;
8280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkScriptValue2 callbackResult;
8290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        success = (*callBack)->getReference(field, len, &callbackResult);
8300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (success) {
8310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (callbackResult.fType == SkOperand2::kString)
8320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                track(callbackResult.fOperand.fString);
8330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            callbackResult.fIsConstant = SkScriptValue2::kVariable;
8340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fValueStack.push(callbackResult);
8350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            goto done;
8360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
8370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return false;
8390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectdone:
8400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return success;
8410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
8420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkScriptEngine2::handleMemberFunction(const char* field, size_t len, void* object,
8440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                           SkTDArray<SkScriptValue2>* params) {
8450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool success = true;
8460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    for (SkScriptCallBack** callBack = fCallBackArray.begin(); callBack < fCallBackArray.end(); callBack++) {
8470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if ((*callBack)->getType() != SkScriptCallBack::kMemberFunction)
8480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            continue;
8490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkScriptValue2 callbackResult;
8500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        success = (*callBack)->getReference(field, len, &callbackResult);
8510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (success) {
8520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (callbackResult.fType == SkOperand2::kString)
8530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                track(callbackResult.fOperand.fString);
8540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            callbackResult.fIsConstant = SkScriptValue2::kVariable;
8550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fValueStack.push(callbackResult);
8560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            goto done;
8570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
8580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return false;
8600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectdone:
8610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return success;
8620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
8630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkScriptEngine2::handleProperty() {
8650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool success = true;
8660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    for (SkScriptCallBack** callBack = fCallBackArray.begin(); callBack < fCallBackArray.end(); callBack++) {
8670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if ((*callBack)->getType() != SkScriptCallBack::kProperty)
8680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            continue;
8690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkScriptValue2 callbackResult;
8700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        success = (*callBack)->getReference(fToken, fTokenLength, &callbackResult);
8710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (success) {
8720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (callbackResult.fType == SkOperand2::kString && callbackResult.fOperand.fString == NULL) {
8730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                callbackResult.fOperand.fString = new SkString(fToken, fTokenLength);
8740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                track(callbackResult.fOperand.fString);
8750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
8760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            callbackResult.fIsConstant = SkScriptValue2::kVariable;
8770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fValueStack.push(callbackResult);
8780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            goto done;
8790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
8800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectdone:
8820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fTokenLength = 0;
8830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return success;
8840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
8850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
8860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkScriptEngine2::handleUnbox(SkScriptValue2* scriptValue) {
8870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool success = true;
8880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    for (SkScriptCallBack** callBack = fCallBackArray.begin(); callBack < fCallBackArray.end(); callBack++) {
8890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if ((*callBack)->getType() != SkScriptCallBack::kUnbox)
8900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            continue;
8910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkScriptCallBackConvert* callBackConvert = (SkScriptCallBackConvert*) *callBack;
8920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        success = callBackConvert->convert(scriptValue->fType, &scriptValue->fOperand);
8930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (success) {
8940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (scriptValue->fType == SkOperand2::kString)
8950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                track(scriptValue->fOperand.fString);
8960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            goto done;
8970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
8980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
8990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return false;
9000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectdone:
9010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return success;
9020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
9030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project// note that entire expression is treated as if it were enclosed in parens
9050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project// an open paren is always the first thing in the op stack
9060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectint SkScriptEngine2::logicalOp(char ch, char nextChar) {
9080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int advance = 1;
9090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Op op;
9100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    signed char precedence;
9110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    switch (ch) {
9120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case ')':
9130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            op = (Op) kParen;
9140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
9150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case ']':
9160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            op = (Op) kArrayOp;
9170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
9180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case '?':
9190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            op = (Op) kIf;
9200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
9210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case ':':
9220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            op = (Op) kElse;
9230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
9240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case '&':
9250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (nextChar != '&')
9260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                goto noMatch;
9270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            op = kLogicalAnd;
9280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            advance = 2;
9290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
9300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case '|':
9310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (nextChar != '|')
9320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                goto noMatch;
9330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            op = kLogicalOr;
9340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            advance = 2;
9350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
9360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        default:
9370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            noMatch:
9380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return 0;
9390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
9400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    precedence = gPrecedence[op];
9410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    int branchIndex = 0;
9420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fBranchPopAllowed = false;
9430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    do {
9440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        while (gPrecedence[fOpStack.top() & ~kArtificialOp] < precedence)
9450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            processOp();
9460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Branch& branch = fBranchStack.index(branchIndex++);
9470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        Op branchOp = branch.fOperator;
9480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (gPrecedence[branchOp] >= precedence)
9490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
9500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        addTokenValue(fValueStack.top(), kAccumulator);
9510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fValueStack.pop();
9520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (branchOp == kLogicalAnd || branchOp == kLogicalOr) {
9530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (branch.fOperator == kLogicalAnd)
9540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                branch.prime();
9550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            addToken(kToBool);
9560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } else
9570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            resolveBranch(branch);
9580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (branch.fDone == Branch::kIsNotDone)
9590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            branch.prime();
9600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } while (true);
9610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fBranchPopAllowed = true;
9620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    while (fBranchStack.top().fDone == Branch::kIsDone)
9630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fBranchStack.pop();
9640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    processLogicalOp(op);
9650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return advance;
9660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
9670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
9680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkScriptEngine2::processLogicalOp(Op op) {
9690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    switch (op) {
9700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case kParen:
9710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case kArrayOp:
9720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(fOpStack.count() > 1 && fOpStack.top() == op);    // !!! add error handling
9730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (op == kParen)
9740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                fOpStack.pop();
9750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            else {
9760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkScriptValue2 value;
9770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                fValueStack.pop(&value);
9780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkASSERT(value.fType == SkOperand2::kS32 || value.fType == SkOperand2::kScalar); // !!! add error handling (although, could permit strings eventually)
9790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                int index = value.fType == SkOperand2::kScalar ? SkScalarFloor(value.fOperand.fScalar) :
9800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    value.fOperand.fS32;
9810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkScriptValue2 arrayValue;
9820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                fValueStack.pop(&arrayValue);
9830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkASSERT(arrayValue.fType == SkOperand2::kArray);  // !!! add error handling
9840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkOpArray* array = arrayValue.fOperand.fArray;
9850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkOperand2 operand;
9860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                bool success = array->getIndex(index, &operand);
9870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkASSERT(success); // !!! add error handling
9880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkScriptValue2 resultValue;
9890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                resultValue.fType = array->getType();
9900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                resultValue.fOperand = operand;
9910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                resultValue.fIsConstant = SkScriptValue2::kVariable;
9920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                fValueStack.push(resultValue);
9930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
9940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                break;
9950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case kIf: {
9960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (fAccumulatorType == SkOperand2::kNoType) {
9970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                addTokenValue(fValueStack.top(), kAccumulator);
9980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                fValueStack.pop();
9990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
10000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(fAccumulatorType != SkOperand2::kString); // !!! add error handling
10010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            addToken(kIfOp);
10020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            Branch branch(op, fOpStack.count(), getTokenOffset());
10030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            *fBranchStack.push() = branch;
10040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            addTokenInt(0); // placeholder for future branch
10050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fAccumulatorType = SkOperand2::kNoType;
10060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } break;
10070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case kElse: {
10080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            addTokenValue(fValueStack.top(), kAccumulator);
10090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fValueStack.pop();
10100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            addToken(kElseOp);
10110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            size_t newOffset = getTokenOffset();
10120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            addTokenInt(0); // placeholder for future branch
10130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            Branch& branch = fBranchStack.top();
10140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            resolveBranch(branch);
10150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            branch.fOperator = op;
10160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            branch.fDone = Branch::kIsNotDone;
10170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(branch.fOpStackDepth == fOpStack.count());
10180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            branch.fOffset = newOffset;
10190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fAccumulatorType = SkOperand2::kNoType;
10200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } break;
10210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case kLogicalAnd:
10220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case kLogicalOr: {
10230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            Branch& oldTop = fBranchStack.top();
10240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            Branch::Primed wasPrime = oldTop.fPrimed;
10250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            Branch::Done wasDone = oldTop.fDone;
10260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            oldTop.fPrimed = Branch::kIsNotPrimed;
10270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            oldTop.fDone = Branch::kIsNotDone;
10280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (fAccumulatorType == SkOperand2::kNoType) {
10290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkASSERT(fValueStack.top().fType == SkOperand2::kS32); // !!! add error handling, and conversion to int?
10300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                addTokenValue(fValueStack.top(), kAccumulator);
10310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                fValueStack.pop();
10320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            } else
10330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkASSERT(fAccumulatorType == SkOperand2::kS32);
10340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            // if 'and', write beq goto opcode after end of predicate (after to bool)
10350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            // if 'or', write bne goto to bool
10360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            addToken(op == kLogicalAnd ? kLogicalAndInt : kLogicalOrInt);
10370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            Branch branch(op, fOpStack.count(), getTokenOffset());
10380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            addTokenInt(0); // placeholder for future branch
10390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            oldTop.fPrimed = wasPrime;
10400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            oldTop.fDone = wasDone;
10410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            *fBranchStack.push() = branch;
10420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fAccumulatorType = SkOperand2::kNoType;
10430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }    break;
10440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        default:
10450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(0);
10460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
10470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
10480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
10490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkScriptEngine2::processOp() {
10500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Op op;
10510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fOpStack.pop(&op);
10520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    op = (Op) (op & ~kArtificialOp);
10530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const OperatorAttributes* attributes = &gOpAttributes[op];
10540b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkScriptValue2 value1;
10550b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    memset(&value1, 0, sizeof(SkScriptValue2));
10560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScriptValue2 value2;
10570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fValueStack.pop(&value2);
10580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    value2.fIsWritten = SkScriptValue2::kUnwritten;
10590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    //    SkScriptEngine2::SkTypeOp convert1[3];
10600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    //    SkScriptEngine2::SkTypeOp convert2[3];
10610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    //    SkScriptEngine2::SkTypeOp* convert2Ptr = convert2;
10620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool constantOperands = value2.fIsConstant == SkScriptValue2::kConstant;
10630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (attributes->fLeftType != SkOperand2::kNoType) {
10640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fValueStack.pop(&value1);
10650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        constantOperands &= value1.fIsConstant == SkScriptValue2::kConstant;
10660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        value1.fIsWritten = SkScriptValue2::kUnwritten;
10670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (op == kFlipOps) {
10680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkTSwap(value1, value2);
10690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            fOpStack.pop(&op);
10700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            op = (Op) (op & ~kArtificialOp);
10710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            attributes = &gOpAttributes[op];
10720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (constantOperands == false)
10730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                addToken(kFlipOpsOp);
10740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
10750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (value1.fType == SkOperand2::kObject && (value1.fType & attributes->fLeftType) == 0) {
10760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            value1.fType = getUnboxType(value1.fOperand);
10770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            addToken(kUnboxToken);
10780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
10790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
10800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (value2.fType == SkOperand2::kObject && (value2.fType & attributes->fLeftType) == 0) {
10810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        value1.fType = getUnboxType(value2.fOperand);
10820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        addToken(kUnboxToken2);
10830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
10840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (attributes->fLeftType != SkOperand2::kNoType) {
10850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (value1.fType != value2.fType) {
10860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if ((attributes->fLeftType & SkOperand2::kString) && attributes->fBias & kTowardsString &&
10870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                ((value1.fType | value2.fType) & SkOperand2::kString)) {
10880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (value1.fType == SkOperand2::kS32 || value1.fType == SkOperand2::kScalar) {
10890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    addTokenConst(&value1, kAccumulator, SkOperand2::kString,
10900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                  value1.fType == SkOperand2::kS32 ? kIntToString : kScalarToString);
10910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
10920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (value2.fType == SkOperand2::kS32 || value2.fType == SkOperand2::kScalar) {
10930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    addTokenConst(&value2, kOperand, SkOperand2::kString,
10940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                  value2.fType == SkOperand2::kS32 ? kIntToString2 : kScalarToString2);
10950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                }
10960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            } else if (attributes->fLeftType & SkOperand2::kScalar && ((value1.fType | value2.fType) &
10970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                                                       SkOperand2::kScalar)) {
10980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (value1.fType == SkOperand2::kS32)
10990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    addTokenConst(&value1, kAccumulator, SkOperand2::kScalar, kIntToScalar);
11000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (value2.fType == SkOperand2::kS32)
11010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    addTokenConst(&value2, kOperand, SkOperand2::kScalar, kIntToScalar2);
11020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
11030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
11040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if ((value1.fType & attributes->fLeftType) == 0 || value1.fType != value2.fType) {
11050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (value1.fType == SkOperand2::kString)
11060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                addTokenConst(&value1, kAccumulator, SkOperand2::kScalar, kStringToScalar);
11070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (value1.fType == SkOperand2::kScalar && (attributes->fLeftType == SkOperand2::kS32 ||
11080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                                        value2.fType == SkOperand2::kS32))
11090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                addTokenConst(&value1, kAccumulator, SkOperand2::kS32, kScalarToInt);
11100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
11110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
11120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    AddTokenRegister rhRegister = attributes->fLeftType != SkOperand2::kNoType ?
11130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        kOperand : kAccumulator;
11140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if ((value2.fType & attributes->fRightType) == 0 || value1.fType != value2.fType) {
11150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (value2.fType == SkOperand2::kString)
11160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            addTokenConst(&value2, rhRegister, SkOperand2::kScalar, kStringToScalar2);
11170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (value2.fType == SkOperand2::kScalar && (attributes->fRightType == SkOperand2::kS32 ||
11180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                                                    value1.fType == SkOperand2::kS32))
11190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            addTokenConst(&value2, rhRegister, SkOperand2::kS32, kScalarToInt2);
11200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
11210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    TypeOp typeOp = gTokens[op];
11220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (value2.fType == SkOperand2::kScalar)
11230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        typeOp = (TypeOp) (typeOp + 1);
11240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else if (value2.fType == SkOperand2::kString)
11250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        typeOp = (TypeOp) (typeOp + 2);
11260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkDynamicMemoryWStream stream;
11270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkOperand2::OpType saveType;
11280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkBool saveOperand;
11290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (constantOperands) {
11300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fActiveStream = &stream;
11310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        saveType = fAccumulatorType;
11320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        saveOperand = fOperandInUse;
11330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fAccumulatorType = SkOperand2::kNoType;
11340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fOperandInUse = false;
11350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
11360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (attributes->fLeftType != SkOperand2::kNoType) {    // two operands
11370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (value1.fIsWritten == SkScriptValue2::kUnwritten)
11380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            addTokenValue(value1, kAccumulator);
11390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
11400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (value2.fIsWritten == SkScriptValue2::kUnwritten)
11410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        addTokenValue(value2, rhRegister);
11420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    addToken(typeOp);
11430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (constantOperands) {
11440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        addToken(kEnd);
11450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
11460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        decompile((const unsigned char*) stream.getStream(), stream.getOffset());
11470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
11480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkScriptRuntime runtime(fCallBackArray);
11490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        runtime.executeTokens((unsigned char*) stream.getStream());
11500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        runtime.getResult(&value1.fOperand);
11510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (attributes->fResultIsBoolean == kResultIsBoolean)
11520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            value1.fType = SkOperand2::kS32;
11530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        else if (attributes->fLeftType == SkOperand2::kNoType) // unary operand
11540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            value1.fType = value2.fType;
11550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fValueStack.push(value1);
11560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        if (value1.fType == SkOperand2::kString)
11570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            runtime.untrack(value1.fOperand.fString);
11580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        else if (value1.fType == SkOperand2::kArray)
11590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            runtime.untrack(value1.fOperand.fArray);
11600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fActiveStream = &fStream;
11610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fAccumulatorType = saveType;
11620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fOperandInUse = saveOperand;
11630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return true;
11640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
11650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    value2.fIsConstant = SkScriptValue2::kVariable;
11660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fValueStack.push(value2);
11670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return true;
11680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
11690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkScriptEngine2::Branch::resolve(SkDynamicMemoryWStream* stream, size_t off) {
11710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(fDone == kIsNotDone);
11720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fPrimed = kIsNotPrimed;
11730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fDone = kIsDone;
11740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(off > fOffset + sizeof(size_t));
11750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    size_t offset = off - fOffset - sizeof(offset);
11760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    stream->write(&offset, fOffset, sizeof(offset));
11770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
11780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkScriptEngine2::resolveBranch(SkScriptEngine2::Branch& branch) {
11800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    branch.resolve(fActiveStream, getTokenOffset());
11810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
11820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
11830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkScriptEngine2::ConvertTo(SkScriptEngine2* engine, SkOperand2::OpType toType, SkScriptValue2* value ) {
11840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkASSERT(value);
11850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkOperand2::OpType type = value->fType;
11860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (type == toType)
11870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        return true;
11880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkOperand2& operand = value->fOperand;
11890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    bool success = true;
11900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    switch (toType) {
11910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkOperand2::kS32:
11920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (type == SkOperand2::kScalar)
11930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                operand.fS32 = SkScalarFloor(operand.fScalar);
11940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            else {
11950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkASSERT(type == SkOperand2::kString);
11960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                success = SkParse::FindS32(operand.fString->c_str(), &operand.fS32) != NULL;
11970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
11980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                break;
11990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkOperand2::kScalar:
12000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (type == SkOperand2::kS32)
12010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                operand.fScalar = IntToScalar(operand.fS32);
12020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            else {
12030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkASSERT(type == SkOperand2::kString);
12040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                success = SkParse::FindScalar(operand.fString->c_str(), &operand.fScalar) != NULL;
12050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
12060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                break;
12070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkOperand2::kString: {
12080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkString* strPtr = new SkString();
12090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(engine);
12100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            engine->track(strPtr);
12110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            if (type == SkOperand2::kS32)
12120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                strPtr->appendS32(operand.fS32);
12130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            else {
12140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkASSERT(type == SkOperand2::kScalar);
12150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                strPtr->appendScalar(operand.fScalar);
12160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            }
12170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            operand.fString = strPtr;
12180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } break;
12190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkOperand2::kArray: {
12200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkOpArray* array = new SkOpArray(type);
12210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            *array->append() = operand;
12220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            engine->track(array);
12230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            operand.fArray = array;
12240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        } break;
12250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        default:
12260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(0);
12270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
12280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    value->fType = toType;
12290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return success;
12300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
12310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source ProjectSkScalar SkScriptEngine2::IntToScalar(int32_t s32) {
12330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkScalar scalar;
12340b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    if (s32 == (int32_t) SK_NaN32)
12350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        scalar = SK_ScalarNaN;
12360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else if (SkAbs32(s32) == SK_MaxS32)
12370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        scalar = SkSign32(s32) * SK_ScalarMax;
12380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    else
12390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        scalar = SkIntToScalar(s32);
12400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return scalar;
12410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
12420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectbool SkScriptEngine2::ValueToString(const SkScriptValue2& value, SkString* string) {
12440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    switch (value.fType) {
12450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkOperand2::kS32:
12460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            string->reset();
12470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            string->appendS32(value.fOperand.fS32);
12480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
12490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkOperand2::kScalar:
12500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            string->reset();
12510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            string->appendScalar(value.fOperand.fScalar);
12520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
12530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        case SkOperand2::kString:
12540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            string->set(*value.fOperand.fString);
12550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            break;
12560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        default:
12570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            SkASSERT(0);
12580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            return false;
12590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
12600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return true; // no error
12610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
12620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_DEBUG
12640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12650b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#define testInt(expression) { #expression, SkOperand2::kS32, expression, 0, NULL }
12660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_SCALAR_IS_FLOAT
12670b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#define testScalar(expression) { #expression, SkOperand2::kScalar, 0, (float) expression, NULL }
12680b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#define testRemainder(exp1, exp2) { #exp1 "%" #exp2, SkOperand2::kScalar, 0, fmodf(exp1, exp2), NULL }
12690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#else
12700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_CAN_USE_FLOAT
12710b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#define testScalar(expression) { #expression, SkOperand2::kScalar, 0, (int) ((expression) * 65536.0f), NULL }
12720b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#define testRemainder(exp1, exp2) { #exp1 "%" #exp2, SkOperand2::kScalar, 0, (int) (fmod(exp1, exp2)  * 65536.0f), NULL }
12730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
12740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
12750b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#define testTrue(expression) { #expression, SkOperand2::kS32, 1, 0, NULL }
12760b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger#define testFalse(expression) { #expression, SkOperand2::kS32, 0, 0, NULL }
12770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
12780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectstatic const SkScriptNAnswer2 scriptTests[]  = {
12790b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    testInt(1||(0&&3)),
12800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_CAN_USE_FLOAT
12810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testScalar(- -5.5- -1.5),
12820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testScalar(1.0+5),
12830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
12840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt((6+7)*8),
12850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(3*(4+5)),
12860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_CAN_USE_FLOAT
12870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testScalar(1.0+2.0),
12880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testScalar(3.0-1.0),
12890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testScalar(6-1.0),
12900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testScalar(2.5*6.),
12910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testScalar(0.5*4),
12920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testScalar(4.5/.5),
12930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testScalar(9.5/19),
12940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testRemainder(9.5, 0.5),
12950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testRemainder(9.,2),
12960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testRemainder(9,2.5),
12970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testRemainder(-9,2.5),
12980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testTrue(-9==-9.0),
12990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testTrue(-9.==-4.0-5),
13000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testTrue(-9.*1==-4-5),
13010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testFalse(-9!=-9.0),
13020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testFalse(-9.!=-4.0-5),
13030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testFalse(-9.*1!=-4-5),
13040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
13050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(0x123),
13060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(0XABC),
13070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(0xdeadBEEF),
13080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {    "'123'+\"456\"", SkOperand2::kString, 0, 0, "123456" },
13090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {    "123+\"456\"", SkOperand2::kString, 0, 0, "123456" },
13100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    {    "'123'+456", SkOperand2::kString, 0, 0, "123456" },
13110b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    {    "'123'|\"456\"", SkOperand2::kS32, 123|456, 0, NULL },
13120b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    {    "123|\"456\"", SkOperand2::kS32, 123|456, 0, NULL },
13130b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    {    "'123'|456", SkOperand2::kS32, 123|456, 0, NULL },
13140b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    {    "'2'<11", SkOperand2::kS32, 1, 0, NULL },
13150b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    {    "2<'11'", SkOperand2::kS32, 1, 0, NULL },
13160b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    {    "'2'<'11'", SkOperand2::kS32, 0, 0, NULL },
13170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(123),
13180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(-345),
13190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(+678),
13200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(1+2+3),
13210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(3*4+5),
13220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(6+7*8),
13230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(-1-2-8/4),
13240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(-9%4),
13250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(9%-4),
13260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(-9%-4),
13270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(123|978),
13280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(123&978),
13290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(123^978),
13300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2<<4),
13310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(99>>3),
13320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(~55),
13330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(~~55),
13340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(!55),
13350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(!!55),
13360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // both int
13370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2<2),
13380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2<11),
13390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(20<11),
13400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2<=2),
13410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2<=11),
13420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(20<=11),
13430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2>2),
13440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2>11),
13450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(20>11),
13460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2>=2),
13470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2>=11),
13480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(20>=11),
13490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2==2),
13500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2==11),
13510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(20==11),
13520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2!=2),
13530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2!=11),
13540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(20!=11),
13550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_CAN_USE_FLOAT
13560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // left int, right scalar
13570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2<2.),
13580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2<11.),
13590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(20<11.),
13600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2<=2.),
13610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2<=11.),
13620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(20<=11.),
13630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2>2.),
13640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2>11.),
13650910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(20>11.),
13660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2>=2.),
13670910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2>=11.),
13680910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(20>=11.),
13690910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2==2.),
13700910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2==11.),
13710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(20==11.),
13720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2!=2.),
13730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2!=11.),
13740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(20!=11.),
13750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // left scalar, right int
13760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2.<2),
13770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2.<11),
13780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(20.<11),
13790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2.<=2),
13800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2.<=11),
13810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(20.<=11),
13820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2.>2),
13830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2.>11),
13840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(20.>11),
13850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2.>=2),
13860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2.>=11),
13870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(20.>=11),
13880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2.==2),
13890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2.==11),
13900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(20.==11),
13910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2.!=2),
13920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2.!=11),
13930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(20.!=11),
13940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // both scalar
13950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2.<11.),
13960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(20.<11.),
13970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2.<=2.),
13980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2.<=11.),
13990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(20.<=11.),
14000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2.>2.),
14010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2.>11.),
14020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(20.>11.),
14030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2.>=2.),
14040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2.>=11.),
14050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(20.>=11.),
14060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2.==2.),
14070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2.==11.),
14080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(20.==11.),
14090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2.!=2.),
14100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(2.!=11.),
14110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(20.!=11.),
14120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
14130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // int, string (string is int)
14140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testFalse(2<'2'),
14150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testTrue(2<'11'),
14160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testFalse(20<'11'),
14170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testTrue(2<='2'),
14180910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testTrue(2<='11'),
14190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testFalse(20<='11'),
14200910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testFalse(2>'2'),
14210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testFalse(2>'11'),
14220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testTrue(20>'11'),
14230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testTrue(2>='2'),
14240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testFalse(2>='11'),
14250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testTrue(20>='11'),
14260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testTrue(2=='2'),
14270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testFalse(2=='11'),
14280910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testFalse(2!='2'),
14290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testTrue(2!='11'),
14300910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // int, string (string is scalar)
14310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testFalse(2<'2.'),
14320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testTrue(2<'11.'),
14330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testFalse(20<'11.'),
14340910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testTrue(2=='2.'),
14350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testFalse(2=='11.'),
14360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_CAN_USE_FLOAT
14370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // scalar, string
14380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testFalse(2.<'2.'),
14390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testTrue(2.<'11.'),
14400910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testFalse(20.<'11.'),
14410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testTrue(2.=='2.'),
14420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testFalse(2.=='11.'),
14430910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // string, int
14440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testFalse('2'<2),
14450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testTrue('2'<11),
14460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testFalse('20'<11),
14470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testTrue('2'==2),
14480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testFalse('2'==11),
14490910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // string, scalar
14500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testFalse('2'<2.),
14510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testTrue('2'<11.),
14520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testFalse('20'<11.),
14530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testTrue('2'==2.),
14540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testFalse('2'==11.),
14550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
14560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // string, string
14570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testFalse('2'<'2'),
14580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testFalse('2'<'11'),
14590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testFalse('20'<'11'),
14600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testTrue('2'=='2'),
14610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testFalse('2'=='11'),
14620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    // logic
14630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(1?2:3),
14640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(0?2:3),
14650b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    testInt((1&&2)||3),
14660b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    testInt((1&&0)||3),
14670b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    testInt((1&&0)||0),
14680b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    testInt(1||(0&&3)),
14690b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    testInt(0||(0&&3)),
14700b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    testInt(0||(1&&3)),
14710910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    testInt(0&&1?2:3)
14720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_CAN_USE_FLOAT
14730b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    , {    "123.5", SkOperand2::kScalar, 0, SkIntToScalar(123) + SK_Scalar1/2, NULL }
14740910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
14750910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
14760910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14770910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#define SkScriptNAnswer_testCount    SK_ARRAY_COUNT(scriptTests)
14780910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
14790910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid SkScriptEngine2::UnitTest() {
148087a2a317c4e99c547ecbfa81f40f7bd7f2932433Mike Reed#if defined(SK_SUPPORT_UNITTEST)
14810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    ValidateDecompileTable();
14820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    for (int index = 0; index < SkScriptNAnswer_testCount; index++) {
14830910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkScriptEngine2 engine(scriptTests[index].fType);
14840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkScriptValue2 value;
14850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const char* script = scriptTests[index].fScript;
14860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        const char* scriptPtr = script;
14870910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(engine.evaluateScript(&scriptPtr, &value) == true);
14880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkASSERT(value.fType == scriptTests[index].fType);
14890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        SkScalar error;
14900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        switch (value.fType) {
14910910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            case SkOperand2::kS32:
14920910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (value.fOperand.fS32 != scriptTests[index].fIntAnswer)
14930910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    SkDEBUGF(("script '%s' == value %d != expected answer %d\n", script, value.fOperand.fS32, scriptTests[index].fIntAnswer));
14940910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkASSERT(value.fOperand.fS32 == scriptTests[index].fIntAnswer);
14950910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                break;
14960910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            case SkOperand2::kScalar:
14970910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                error = SkScalarAbs(value.fOperand.fScalar - scriptTests[index].fScalarAnswer);
14980910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#ifdef SK_CAN_USE_FLOAT
14990910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                if (error >= SK_Scalar1 / 10000)
15000910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                    SkDEBUGF(("script '%s' == value %g != expected answer %g\n", script, value.fOperand.fScalar / (1.0f * SK_Scalar1), scriptTests[index].fScalarAnswer / (1.0f * SK_Scalar1)));
15010910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
15020910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkASSERT(error < SK_Scalar1 / 10000);
15030910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                break;
15040910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            case SkOperand2::kString:
15050910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkASSERT(value.fOperand.fString->equals(scriptTests[index].fStringAnswer));
15060910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                break;
15070910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project            default:
15080910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project                SkASSERT(0);
15090910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        }
15100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
15110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
15120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
15130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#endif
1514