X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/9dae56ea45a0f5f8136a5c93d6f3a7f99399ca73..f9bf01c6616d5ddcf65b13b33cedf9e387ff7a63:/runtime/JSGlobalObjectFunctions.cpp diff --git a/runtime/JSGlobalObjectFunctions.cpp b/runtime/JSGlobalObjectFunctions.cpp index f9dbe59..2ddc41c 100644 --- a/runtime/JSGlobalObjectFunctions.cpp +++ b/runtime/JSGlobalObjectFunctions.cpp @@ -27,13 +27,16 @@ #include "CallFrame.h" #include "GlobalEvalFunction.h" +#include "Interpreter.h" #include "JSGlobalObject.h" #include "JSString.h" -#include "Interpreter.h" -#include "Parser.h" -#include "dtoa.h" #include "Lexer.h" +#include "LiteralParser.h" #include "Nodes.h" +#include "Parser.h" +#include "StringBuilder.h" +#include "StringExtras.h" +#include "dtoa.h" #include #include #include @@ -47,32 +50,32 @@ using namespace Unicode; namespace JSC { -static JSValuePtr encode(ExecState* exec, const ArgList& args, const char* doNotEscape) +static JSValue encode(ExecState* exec, const ArgList& args, const char* doNotEscape) { - UString str = args.at(exec, 0).toString(exec); + UString str = args.at(0).toString(exec); CString cstr = str.UTF8String(true); if (!cstr.c_str()) return throwError(exec, URIError, "String contained an illegal UTF-16 sequence."); - UString result = ""; + StringBuilder builder; const char* p = cstr.c_str(); for (size_t k = 0; k < cstr.size(); k++, p++) { char c = *p; if (c && strchr(doNotEscape, c)) - result.append(c); + builder.append(c); else { char tmp[4]; snprintf(tmp, sizeof(tmp), "%%%02X", static_cast(c)); - result += tmp; + builder.append((const char*)tmp); } } - return jsString(exec, result); + return jsString(exec, builder.release()); } -static JSValuePtr decode(ExecState* exec, const ArgList& args, const char* doNotUnescape, bool strict) +static JSValue decode(ExecState* exec, const ArgList& args, const char* doNotUnescape, bool strict) { - UString result = ""; - UString str = args.at(exec, 0).toString(exec); + StringBuilder builder; + UString str = args.at(0).toString(exec); int k = 0; int len = str.size(); const UChar* d = str.data(); @@ -105,7 +108,7 @@ static JSValuePtr decode(ExecState* exec, const ArgList& args, const char* doNot charLen = 0; else if (character >= 0x10000) { // Convert to surrogate pair. - result.append(static_cast(0xD800 | ((character - 0x10000) >> 10))); + builder.append(static_cast(0xD800 | ((character - 0x10000) >> 10))); u = static_cast(0xDC00 | ((character - 0x10000) & 0x3FF)); } else u = static_cast(character); @@ -130,9 +133,9 @@ static JSValuePtr decode(ExecState* exec, const ArgList& args, const char* doNot } } k++; - result.append(c); + builder.append(c); } - return jsString(exec, result); + return jsString(exec, builder.release()); } bool isStrWhiteSpace(UChar c) @@ -268,67 +271,71 @@ static double parseFloat(const UString& s) return s.toDouble(true /*tolerant*/, false /* NaN for empty string */); } -JSValuePtr globalFuncEval(ExecState* exec, JSObject* function, JSValuePtr thisValue, const ArgList& args) +JSValue JSC_HOST_CALL globalFuncEval(ExecState* exec, JSObject* function, JSValue thisValue, const ArgList& args) { JSObject* thisObject = thisValue.toThisObject(exec); JSObject* unwrappedObject = thisObject->unwrappedObject(); if (!unwrappedObject->isGlobalObject() || static_cast(unwrappedObject)->evalFunction() != function) return throwError(exec, EvalError, "The \"this\" value passed to eval must be the global object from which eval originated"); - JSValuePtr x = args.at(exec, 0); + JSValue x = args.at(0); if (!x.isString()) return x; UString s = x.toString(exec); - int errLine; - UString errMsg; - - SourceCode source = makeSource(s); - RefPtr evalNode = exec->globalData().parser->parse(exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg); + LiteralParser preparser(exec, s, LiteralParser::NonStrictJSON); + if (JSValue parsedObject = preparser.tryLiteralParse()) + return parsedObject; - if (!evalNode) - return throwError(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), NULL); + RefPtr eval = EvalExecutable::create(exec, makeSource(s)); + JSObject* error = eval->compile(exec, static_cast(unwrappedObject)->globalScopeChain().node()); + if (error) + return throwError(exec, error); - return exec->interpreter()->execute(evalNode.get(), exec, thisObject, static_cast(unwrappedObject)->globalScopeChain().node(), exec->exceptionSlot()); + return exec->interpreter()->execute(eval.get(), exec, thisObject, static_cast(unwrappedObject)->globalScopeChain().node(), exec->exceptionSlot()); } -JSValuePtr globalFuncParseInt(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args) +JSValue JSC_HOST_CALL globalFuncParseInt(ExecState* exec, JSObject*, JSValue, const ArgList& args) { - JSValuePtr value = args.at(exec, 0); - int32_t radix = args.at(exec, 1).toInt32(exec); + JSValue value = args.at(0); + int32_t radix = args.at(1).toInt32(exec); + + if (radix != 0 && radix != 10) + return jsNumber(exec, parseInt(value.toString(exec), radix)); + + if (value.isInt32()) + return value; - if (value.isNumber() && (radix == 0 || radix == 10)) { - if (value.isInt32Fast()) - return value; - double d = value.uncheckedGetNumber(); + if (value.isDouble()) { + double d = value.asDouble(); if (isfinite(d)) return jsNumber(exec, (d > 0) ? floor(d) : ceil(d)); if (isnan(d) || isinf(d)) - return jsNaN(&exec->globalData()); - return js0(); + return jsNaN(exec); + return jsNumber(exec, 0); } return jsNumber(exec, parseInt(value.toString(exec), radix)); } -JSValuePtr globalFuncParseFloat(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args) +JSValue JSC_HOST_CALL globalFuncParseFloat(ExecState* exec, JSObject*, JSValue, const ArgList& args) { - return jsNumber(exec, parseFloat(args.at(exec, 0).toString(exec))); + return jsNumber(exec, parseFloat(args.at(0).toString(exec))); } -JSValuePtr globalFuncIsNaN(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args) +JSValue JSC_HOST_CALL globalFuncIsNaN(ExecState* exec, JSObject*, JSValue, const ArgList& args) { - return jsBoolean(isnan(args.at(exec, 0).toNumber(exec))); + return jsBoolean(isnan(args.at(0).toNumber(exec))); } -JSValuePtr globalFuncIsFinite(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args) +JSValue JSC_HOST_CALL globalFuncIsFinite(ExecState* exec, JSObject*, JSValue, const ArgList& args) { - double n = args.at(exec, 0).toNumber(exec); + double n = args.at(0).toNumber(exec); return jsBoolean(!isnan(n) && !isinf(n)); } -JSValuePtr globalFuncDecodeURI(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args) +JSValue JSC_HOST_CALL globalFuncDecodeURI(ExecState* exec, JSObject*, JSValue, const ArgList& args) { static const char do_not_unescape_when_decoding_URI[] = "#$&+,/:;=?@"; @@ -336,12 +343,12 @@ JSValuePtr globalFuncDecodeURI(ExecState* exec, JSObject*, JSValuePtr, const Arg return decode(exec, args, do_not_unescape_when_decoding_URI, true); } -JSValuePtr globalFuncDecodeURIComponent(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args) +JSValue JSC_HOST_CALL globalFuncDecodeURIComponent(ExecState* exec, JSObject*, JSValue, const ArgList& args) { return decode(exec, args, "", true); } -JSValuePtr globalFuncEncodeURI(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args) +JSValue JSC_HOST_CALL globalFuncEncodeURI(ExecState* exec, JSObject*, JSValue, const ArgList& args) { static const char do_not_escape_when_encoding_URI[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" @@ -352,7 +359,7 @@ JSValuePtr globalFuncEncodeURI(ExecState* exec, JSObject*, JSValuePtr, const Arg return encode(exec, args, do_not_escape_when_encoding_URI); } -JSValuePtr globalFuncEncodeURIComponent(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args) +JSValue JSC_HOST_CALL globalFuncEncodeURIComponent(ExecState* exec, JSObject*, JSValue, const ArgList& args) { static const char do_not_escape_when_encoding_URI_component[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" @@ -363,7 +370,7 @@ JSValuePtr globalFuncEncodeURIComponent(ExecState* exec, JSObject*, JSValuePtr, return encode(exec, args, do_not_escape_when_encoding_URI_component); } -JSValuePtr globalFuncEscape(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args) +JSValue JSC_HOST_CALL globalFuncEscape(ExecState* exec, JSObject*, JSValue, const ArgList& args) { static const char do_not_escape[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" @@ -371,9 +378,9 @@ JSValuePtr globalFuncEscape(ExecState* exec, JSObject*, JSValuePtr, const ArgLis "0123456789" "*+-./@_"; - UString result = ""; + StringBuilder builder; UString s; - UString str = args.at(exec, 0).toString(exec); + UString str = args.at(0).toString(exec); const UChar* c = str.data(); for (int k = 0; k < str.size(); k++, c++) { int u = c[0]; @@ -388,44 +395,44 @@ JSValuePtr globalFuncEscape(ExecState* exec, JSObject*, JSValuePtr, const ArgLis snprintf(tmp, sizeof(tmp), "%%%02X", u); s = UString(tmp); } - result += s; + builder.append(s); } - return jsString(exec, result); + return jsString(exec, builder.release()); } -JSValuePtr globalFuncUnescape(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args) +JSValue JSC_HOST_CALL globalFuncUnescape(ExecState* exec, JSObject*, JSValue, const ArgList& args) { - UString result = ""; - UString str = args.at(exec, 0).toString(exec); + StringBuilder builder; + UString str = args.at(0).toString(exec); int k = 0; int len = str.size(); while (k < len) { const UChar* c = str.data() + k; UChar u; if (c[0] == '%' && k <= len - 6 && c[1] == 'u') { - if (Lexer::isHexDigit(c[2]) && Lexer::isHexDigit(c[3]) && Lexer::isHexDigit(c[4]) && Lexer::isHexDigit(c[5])) { + if (isASCIIHexDigit(c[2]) && isASCIIHexDigit(c[3]) && isASCIIHexDigit(c[4]) && isASCIIHexDigit(c[5])) { u = Lexer::convertUnicode(c[2], c[3], c[4], c[5]); c = &u; k += 5; } - } else if (c[0] == '%' && k <= len - 3 && Lexer::isHexDigit(c[1]) && Lexer::isHexDigit(c[2])) { + } else if (c[0] == '%' && k <= len - 3 && isASCIIHexDigit(c[1]) && isASCIIHexDigit(c[2])) { u = UChar(Lexer::convertHex(c[1], c[2])); c = &u; k += 2; } k++; - result.append(*c); + builder.append(*c); } - return jsString(exec, result); + return jsString(exec, builder.release()); } #ifndef NDEBUG -JSValuePtr globalFuncJSCPrint(ExecState* exec, JSObject*, JSValuePtr, const ArgList& args) +JSValue JSC_HOST_CALL globalFuncJSCPrint(ExecState* exec, JSObject*, JSValue, const ArgList& args) { CStringBuffer string; - args.at(exec, 0).toString(exec).getCString(string); + args.at(0).toString(exec).getCString(string); puts(string.data()); return jsUndefined(); }