
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "SkScriptRuntime.h"
#include "SkScript2.h"
#include "SkMath.h"
#include "SkParse.h"
#include "SkScriptCallBack.h"
#include "SkString.h"
#include "SkOpArray.h"

// script tokenizer

// turn text into token string
// turn number literals into inline UTF8-style values
// process operators to turn standard notation into stack notation

// defer processing until the tokens can all be resolved
// then, turn token strings into indices into the appropriate tables / dictionaries

// consider: const evaluation?

// replace script string with script tokens preceeded by special value

// need second version of script plugins that return private index of found value?
    // then would need in script index of plugin, private index

// encode brace stack push/pop as opcodes

// should token script enocde type where possible?

// current flow:
    // strip whitespace
    // if in array brace [ recurse, continue
    // if token, handle function, or array, or property (continue)
    // parse number, continue
    // parse token, continue
    // parse string literal, continue
    // if dot operator, handle dot, continue
    // if [ , handle array literal or accessor, continue
    // if ), pop (if function, break)
    // if ], pop ; if ',' break
    // handle logical ops
    // or, handle arithmetic ops
    // loop

// !!! things to do
    // add separate processing loop to advance while suppressed
    // or, include jump offset to skip suppressed code?

SkScriptRuntime::~SkScriptRuntime() {
    for (SkString** stringPtr = fTrackString.begin(); stringPtr < fTrackString.end(); stringPtr++)
        delete *stringPtr;
    for (SkOpArray** arrayPtr = fTrackArray.begin(); arrayPtr < fTrackArray.end(); arrayPtr++)
        delete *arrayPtr;
}

bool SkScriptRuntime::executeTokens(unsigned char* opCode) {
    SkOperand2 operand[2];    // 1=accumulator and 2=operand
    SkScriptEngine2::TypeOp op;
    size_t ref;
    int index, size;
    int registerLoad;
    SkScriptCallBack* callBack SK_INIT_TO_AVOID_WARNING;
    do {
    switch ((op = (SkScriptEngine2::TypeOp) *opCode++)) {
        case SkScriptEngine2::kArrayToken:    // create an array
            operand[0].fArray = new SkOpArray(SkOperand2::kNoType /*fReturnType*/);
            break;
        case SkScriptEngine2::kArrayIndex:    // array accessor
            index = operand[1].fS32;
            if (index >= operand[0].fArray->count()) {
                fError = kArrayIndexOutOfBounds;
                return false;
            }
            operand[0] = operand[0].fArray->begin()[index];
            break;
        case SkScriptEngine2::kArrayParam:    // array initializer, or function param
            *operand[0].fArray->append() = operand[1];
            break;
        case SkScriptEngine2::kCallback:
            memcpy(&index, opCode, sizeof(index));
            opCode += sizeof(index);
            callBack = fCallBackArray[index];
            break;
        case SkScriptEngine2::kFunctionCall: {
            memcpy(&ref, opCode, sizeof(ref));
            opCode += sizeof(ref);
            SkScriptCallBackFunction* callBackFunction = (SkScriptCallBackFunction*) callBack;
            if (callBackFunction->invoke(ref, operand[0].fArray, /* params */
                    &operand[0] /* result */) == false) {
                fError = kFunctionCallFailed;
                return false;
            }
            } break;
        case SkScriptEngine2::kMemberOp: {
            memcpy(&ref, opCode, sizeof(ref));
            opCode += sizeof(ref);
            SkScriptCallBackMember* callBackMember = (SkScriptCallBackMember*) callBack;
            if (callBackMember->invoke(ref, operand[0].fObject, &operand[0]) == false) {
                fError = kMemberOpFailed;
                return false;
            }
            } break;
        case SkScriptEngine2::kPropertyOp: {
            memcpy(&ref, opCode, sizeof(ref));
            opCode += sizeof(ref);
            SkScriptCallBackProperty* callBackProperty = (SkScriptCallBackProperty*) callBack;
            if (callBackProperty->getResult(ref, &operand[0])== false) {
                fError = kPropertyOpFailed;
                return false;
            }
            } break;
        case SkScriptEngine2::kAccumulatorPop:
            fRunStack.pop(&operand[0]);
            break;
        case SkScriptEngine2::kAccumulatorPush:
            *fRunStack.push() = operand[0];
            break;
        case SkScriptEngine2::kIntegerAccumulator:
        case SkScriptEngine2::kIntegerOperand:
            registerLoad = op - SkScriptEngine2::kIntegerAccumulator;
            memcpy(&operand[registerLoad].fS32, opCode, sizeof(int32_t));
            opCode += sizeof(int32_t);
            break;
        case SkScriptEngine2::kScalarAccumulator:
        case SkScriptEngine2::kScalarOperand:
            registerLoad = op - SkScriptEngine2::kScalarAccumulator;
            memcpy(&operand[registerLoad].fScalar, opCode, sizeof(SkScalar));
            opCode += sizeof(SkScalar);
            break;
        case SkScriptEngine2::kStringAccumulator:
        case SkScriptEngine2::kStringOperand: {
            SkString* strPtr = new SkString();
            track(strPtr);
            registerLoad = op - SkScriptEngine2::kStringAccumulator;
            memcpy(&size, opCode, sizeof(size));
            opCode += sizeof(size);
            strPtr->set((char*) opCode, size);
            opCode += size;
            operand[registerLoad].fString = strPtr;
            } break;
        case SkScriptEngine2::kStringTrack: // call after kObjectToValue
            track(operand[0].fString);
            break;
        case SkScriptEngine2::kBoxToken: {
            SkOperand2::OpType type;
            memcpy(&type, opCode, sizeof(type));
            opCode += sizeof(type);
            SkScriptCallBackConvert* callBackBox = (SkScriptCallBackConvert*) callBack;
            if (callBackBox->convert(type, &operand[0]) == false)
                return false;
            } break;
        case SkScriptEngine2::kUnboxToken:
        case SkScriptEngine2::kUnboxToken2: {
            SkScriptCallBackConvert* callBackUnbox = (SkScriptCallBackConvert*) callBack;
            if (callBackUnbox->convert(SkOperand2::kObject, &operand[0]) == false)
                return false;
            } break;
        case SkScriptEngine2::kIfOp:
        case SkScriptEngine2::kLogicalAndInt:
            memcpy(&size, opCode, sizeof(size));
            opCode += sizeof(size);
            if (operand[0].fS32 == 0)
                opCode += size; // skip to else (or end of if predicate)
            break;
        case SkScriptEngine2::kElseOp:
            memcpy(&size, opCode, sizeof(size));
            opCode += sizeof(size);
            opCode += size; // if true: after predicate, always skip to end of else
            break;
        case SkScriptEngine2::kLogicalOrInt:
            memcpy(&size, opCode, sizeof(size));
            opCode += sizeof(size);
            if (operand[0].fS32 != 0)
                opCode += size; // skip to kToBool opcode after || predicate
            break;
        // arithmetic conversion ops
        case SkScriptEngine2::kFlipOpsOp:
            SkTSwap(operand[0], operand[1]);
            break;
        case SkScriptEngine2::kIntToString:
        case SkScriptEngine2::kIntToString2:
        case SkScriptEngine2::kScalarToString:
        case SkScriptEngine2::kScalarToString2:{
            SkString* strPtr = new SkString();
            track(strPtr);
            if (op == SkScriptEngine2::kIntToString || op == SkScriptEngine2::kIntToString2)
                strPtr->appendS32(operand[op - SkScriptEngine2::kIntToString].fS32);
            else
                strPtr->appendScalar(operand[op - SkScriptEngine2::kScalarToString].fScalar);
            operand[0].fString = strPtr;
            } break;
        case SkScriptEngine2::kIntToScalar:
        case SkScriptEngine2::kIntToScalar2:
            operand[0].fScalar = SkScriptEngine2::IntToScalar(operand[op - SkScriptEngine2::kIntToScalar].fS32);
            break;
        case SkScriptEngine2::kStringToInt:
            if (SkParse::FindS32(operand[0].fString->c_str(), &operand[0].fS32) == NULL)
                return false;
            break;
        case SkScriptEngine2::kStringToScalar:
        case SkScriptEngine2::kStringToScalar2:
            if (SkParse::FindScalar(operand[0].fString->c_str(),
                    &operand[op - SkScriptEngine2::kStringToScalar].fScalar) == NULL)
                return false;
            break;
        case SkScriptEngine2::kScalarToInt:
            operand[0].fS32 = SkScalarFloor(operand[0].fScalar);
            break;
        // arithmetic ops
        case SkScriptEngine2::kAddInt:
            operand[0].fS32 += operand[1].fS32;
            break;
        case SkScriptEngine2::kAddScalar:
            operand[0].fScalar += operand[1].fScalar;
            break;
        case SkScriptEngine2::kAddString:
//            if (fTrackString.find(operand[1].fString) < 0) {
//                operand[1].fString = SkNEW_ARGS(SkString, (*operand[1].fString));
//                track(operand[1].fString);
//            }
            operand[0].fString->append(*operand[1].fString);
            break;
        case SkScriptEngine2::kBitAndInt:
            operand[0].fS32 &= operand[1].fS32;
            break;
        case SkScriptEngine2::kBitNotInt:
            operand[0].fS32 = ~operand[0].fS32;
            break;
        case SkScriptEngine2::kBitOrInt:
            operand[0].fS32 |= operand[1].fS32;
            break;
        case SkScriptEngine2::kDivideInt:
            SkASSERT(operand[1].fS32 != 0);
            if (operand[1].fS32 == 0)
                operand[0].fS32 = operand[0].fS32 == 0 ? SK_NaN32 :
                    operand[0].fS32 > 0 ? SK_MaxS32 : -SK_MaxS32;
            else
            if (operand[1].fS32 != 0) // throw error on divide by zero?
                operand[0].fS32 /= operand[1].fS32;
            break;
        case SkScriptEngine2::kDivideScalar:
            if (operand[1].fScalar == 0)
                operand[0].fScalar = operand[0].fScalar == 0 ? SK_ScalarNaN :
                    operand[0].fScalar > 0 ? SK_ScalarMax : -SK_ScalarMax;
            else
                operand[0].fScalar = SkScalarDiv(operand[0].fScalar, operand[1].fScalar);
            break;
        case SkScriptEngine2::kEqualInt:
            operand[0].fS32 = operand[0].fS32 == operand[1].fS32;
            break;
        case SkScriptEngine2::kEqualScalar:
            operand[0].fS32 = operand[0].fScalar == operand[1].fScalar;
            break;
        case SkScriptEngine2::kEqualString:
            operand[0].fS32 = *operand[0].fString == *operand[1].fString;
            break;
        case SkScriptEngine2::kGreaterEqualInt:
            operand[0].fS32 = operand[0].fS32 >= operand[1].fS32;
            break;
        case SkScriptEngine2::kGreaterEqualScalar:
            operand[0].fS32 = operand[0].fScalar >= operand[1].fScalar;
            break;
        case SkScriptEngine2::kGreaterEqualString:
            operand[0].fS32 = strcmp(operand[0].fString->c_str(), operand[1].fString->c_str()) >= 0;
            break;
        case SkScriptEngine2::kToBool:
            operand[0].fS32 = !! operand[0].fS32;
            break;
        case SkScriptEngine2::kLogicalNotInt:
            operand[0].fS32 = ! operand[0].fS32;
            break;
        case SkScriptEngine2::kMinusInt:
            operand[0].fS32 = -operand[0].fS32;
            break;
        case SkScriptEngine2::kMinusScalar:
            operand[0].fScalar = -operand[0].fScalar;
            break;
        case SkScriptEngine2::kModuloInt:
            operand[0].fS32 %= operand[1].fS32;
            break;
        case SkScriptEngine2::kModuloScalar:
            operand[0].fScalar = SkScalarMod(operand[0].fScalar, operand[1].fScalar);
            break;
        case SkScriptEngine2::kMultiplyInt:
            operand[0].fS32 *= operand[1].fS32;
            break;
        case SkScriptEngine2::kMultiplyScalar:
            operand[0].fScalar = SkScalarMul(operand[0].fScalar, operand[1].fScalar);
            break;
        case SkScriptEngine2::kShiftLeftInt:
            operand[0].fS32 <<= operand[1].fS32;
            break;
        case SkScriptEngine2::kShiftRightInt:
            operand[0].fS32 >>= operand[1].fS32;
            break;
        case SkScriptEngine2::kSubtractInt:
            operand[0].fS32 -= operand[1].fS32;
            break;
        case SkScriptEngine2::kSubtractScalar:
            operand[0].fScalar -= operand[1].fScalar;
            break;
        case SkScriptEngine2::kXorInt:
            operand[0].fS32 ^= operand[1].fS32;
            break;
        case SkScriptEngine2::kEnd:
            goto done;
        case SkScriptEngine2::kNop:
                SkASSERT(0);
    default:
        break;
    }
    } while (true);
done:
    fRunStack.push(operand[0]);
    return true;
}

bool SkScriptRuntime::getResult(SkOperand2* result) {
    if (fRunStack.count() == 0)
        return false;
    fRunStack.pop(result);
    return true;
}

void SkScriptRuntime::track(SkOpArray* array) {
    SkASSERT(fTrackArray.find(array) < 0);
    *fTrackArray.append() = array;
}

void SkScriptRuntime::track(SkString* string) {
    SkASSERT(fTrackString.find(string) < 0);
    *fTrackString.append() = string;
}

void SkScriptRuntime::untrack(SkOpArray* array) {
    int index = fTrackArray.find(array);
    SkASSERT(index >= 0);
    fTrackArray.begin()[index] = NULL;
}

void SkScriptRuntime::untrack(SkString* string) {
    int index = fTrackString.find(string);
    SkASSERT(index >= 0);
    fTrackString.begin()[index] = NULL;
}
