Пример #1
0
v8::Local<v8::Value> DotExpressions::AddWorker(const v8::FunctionCallbackInfo<v8::Value>& args)
{
	LOG("@%p", this);
	if (args.Length() != 2)
	{
		ThrowSyntaxError("expected add(name, function)\r\n");
	}

	if (!args[0]->IsString())
	{
		std::stringstream ss;

		ss << "first parameter has to be string\r\n";

		auto s = args[0]->ToString();
		String::Utf8Value str(s);
		ss << (*str);

		ThrowSyntaxError(ss.str().c_str());
	}

	if (!args[1]->IsFunction())
	{
		std::stringstream ss;

		ss << "second parameter has to be a function\r\n";
		ss << *String::Utf8Value(args[1]->ToString());

		ThrowSyntaxError(ss.str().c_str());
	}

	auto token = args[0]->ToString();
	String::Utf8Value strToken(token);

	_Expressions.emplace(std::string(*strToken, strToken.length()), UniquePersistent<Function>(Isolate::GetCurrent(), args[1].As<Function>()));

	return v8::Local<v8::Value>();
}
Пример #2
0
tokens JSONScanner::Scan()
{
    pTokenString = currentChar;

    while (currentChar < inputText + inputLen)
    {
        switch(ReadNextChar())
        {
        case 0:
            //EOF
            currentChar--;
            return (pToken->tk = tkEOF);

        case '\t':
        case '\r':
        case '\n':
        case ' ':
            //WS - keep looping
            break;

        case '"':
            //check for string
            return ScanString();

        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            //decimal digit starts a number
        {
            currentChar--;

            // we use StrToDbl() here for compat with the rest of the engine. StrToDbl() accept a larger syntax.
            // Verify first the JSON grammar.
            const char16* saveCurrentChar = currentChar;
            if(!IsJSONNumber())
            {
                ThrowSyntaxError(JSERR_JsonBadNumber);
            }
            currentChar = saveCurrentChar;
            double val;
            const char16* end;
            val = Js::NumberUtilities::StrToDbl(currentChar, &end, scriptContext);
            if(currentChar == end)
            {
                ThrowSyntaxError(JSERR_JsonBadNumber);
            }
            AssertMsg(!Js::JavascriptNumber::IsNan(val), "Bad result from string to double conversion");
            pToken->tk = tkFltCon;
            pToken->SetDouble(val, false);
            currentChar = end;
            return tkFltCon;
        }

        case ',':
            return (pToken->tk = tkComma);

        case ':':
            return (pToken->tk = tkColon);

        case '[':
            return (pToken->tk = tkLBrack);

        case ']':
            return (pToken->tk = tkRBrack);

        case '-':
            return (pToken->tk = tkSub);

        case 'n':
            //check for 'null'
            if (currentChar + 2 < inputText + inputLen  && currentChar[0] == 'u' && currentChar[1] == 'l' && currentChar[2] == 'l')
            {
                currentChar += 3;
                return (pToken->tk = tkNULL);
            }
            ThrowSyntaxError(JSERR_JsonIllegalChar);

        case 't':
            //check for 'true'
            if (currentChar + 2 < inputText + inputLen  && currentChar[0] == 'r' && currentChar[1] == 'u' && currentChar[2] == 'e')
            {
                currentChar += 3;
                return (pToken->tk = tkTRUE);
            }
            ThrowSyntaxError(JSERR_JsonIllegalChar);

        case 'f':
            //check for 'false'
            if (currentChar + 3 < inputText + inputLen  && currentChar[0] == 'a' && currentChar[1] == 'l' && currentChar[2] == 's' && currentChar[3] == 'e')
            {
                currentChar += 4;
                return (pToken->tk = tkFALSE);
            }
            ThrowSyntaxError(JSERR_JsonIllegalChar);

        case '{':
            return (pToken->tk = tkLCurly);

        case '}':
            return (pToken->tk = tkRCurly);

        default:
            ThrowSyntaxError(JSERR_JsonIllegalChar);
        }

    }

    return (pToken->tk = tkEOF);
}
Пример #3
0
tokens JSONScanner::ScanString()
{
    char16 ch;

    this->currentIndex = 0;
    this->currentString = const_cast<char16*>(currentChar);
    bool endFound = false;
    bool isStringDirectInputTextMapped = true;
    LPCWSTR bulkStart = currentChar;
    uint bulkLength = 0;

    while (currentChar < inputText + inputLen)
    {
        ch = ReadNextChar();
        int tempHex;

        if (ch == '"')
        {
            //end of the string
            endFound = true;
            break;
        }
        else if (ch <= 0x1F)
        {
            //JSON doesn't accept \u0000 - \u001f range, LS(\u2028) and PS(\u2029) are ok
            ThrowSyntaxError(JSERR_JsonIllegalChar);
        }
        else if ( 0 == ch )
        {
            currentChar--;
            ThrowSyntaxError(JSERR_JsonNoStrEnd);
        }
        else if ('\\' == ch)
        {
            //JSON escape sequence in a string \", \/, \\, \b, \f, \n, \r, \t, unicode seq
            // unlikely V5.8 regular chars are not escaped, i.e '\g'' in a string is illegal not 'g'
            if (currentChar >= inputText + inputLen )
            {
                ThrowSyntaxError(JSERR_JsonNoStrEnd);
            }

            ch = ReadNextChar();
            switch (ch)
            {
            case 0:
                currentChar--;
                ThrowSyntaxError(JSERR_JsonNoStrEnd);

            case '"':
            case '/':
            case '\\':
                //keep ch
                break;

            case 'b':
                ch = 0x08;
                break;

            case 'f':
                ch = 0x0C;
                break;

            case 'n':
                ch = 0x0A;
                break;

            case 'r':
                ch = 0x0D;
                break;

            case 't':
                ch = 0x09;
                break;

            case 'u':
            {
                int chcode;
                // 4 hex digits
                if (currentChar + 3 >= inputText + inputLen)
                {
                    //no room left for 4 hex chars
                    ThrowSyntaxError(JSERR_JsonNoStrEnd);

                }
                if (!Js::NumberUtilities::FHexDigit((WCHAR)ReadNextChar(), &tempHex))
                {
                    ThrowSyntaxError(JSERR_JsonBadHexDigit);
                }
                chcode = tempHex * 0x1000;

                if (!Js::NumberUtilities::FHexDigit((WCHAR)ReadNextChar(), &tempHex))
                {
                    ThrowSyntaxError(JSERR_JsonBadHexDigit);
                }
                chcode += tempHex * 0x0100;

                if (!Js::NumberUtilities::FHexDigit((WCHAR)ReadNextChar(), &tempHex))
                {
                    ThrowSyntaxError(JSERR_JsonBadHexDigit);
                }
                chcode += tempHex * 0x0010;

                if (!Js::NumberUtilities::FHexDigit((WCHAR)ReadNextChar(), &tempHex))
                {
                    ThrowSyntaxError(JSERR_JsonBadHexDigit);
                }
                chcode += tempHex;
                AssertMsg(chcode == (chcode & 0xFFFF), "Bad unicode code");
                ch = (char16)chcode;
            }
            break;

            default:
                // Any other '\o' is an error in JSON
                ThrowSyntaxError(JSERR_JsonIllegalChar);
            }

            // flush
            this->GetCurrentRangeCharacterPairList()->Add(RangeCharacterPair((uint)(bulkStart - inputText), bulkLength, ch));

            uint oldIndex = currentIndex;
            currentIndex += bulkLength;
            currentIndex++;

            if (currentIndex < oldIndex)
            {
                // Overflow
                Js::Throw::OutOfMemory();
            }

            // mark the mode as 'string transformed' (no direct mapping in inputText possible)
            isStringDirectInputTextMapped = false;

            // reset (to next char)
            bulkStart = currentChar;
            bulkLength = 0;
        }
        else
        {
            // continue
            bulkLength++;
        }
    }

    if (!endFound)
    {
        // no ending '"' found
        ThrowSyntaxError(JSERR_JsonNoStrEnd);
    }

    if (isStringDirectInputTextMapped == false)
    {
        // If the last bulk is not ended with an escape character, make sure that is
        // not built into the final unescaped string
        bool shouldSkipLastCharacter = false;
        if (bulkLength > 0)
        {
            shouldSkipLastCharacter = true;
            this->GetCurrentRangeCharacterPairList()->Add(RangeCharacterPair((uint)(bulkStart - inputText), bulkLength, _u('\0')));
            uint oldIndex = currentIndex;
            currentIndex += bulkLength;
            if (currentIndex < oldIndex)
            {
                // Overflow
                Js::Throw::OutOfMemory();
            }
        }

        this->BuildUnescapedString(shouldSkipLastCharacter);
        this->GetCurrentRangeCharacterPairList()->Clear();
        this->currentString = this->stringBuffer;
    }
    else
    {
        // make currentIndex the length (w/o the \0)
        currentIndex = bulkLength;

        OUTPUT_TRACE_DEBUGONLY(Js::JSONPhase, _u("ScanString(): direct-mapped string as '%.*s'\n"),
                               GetCurrentStringLen(), GetCurrentString());
    }

    return (pToken->tk = tkStrCon);
}