X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/ba379fdc102753d6be2c4d937058fe40257329fe..4e4e5a6f2694187498445a6ac6f1634ce8141119:/runtime/JSGlobalObjectFunctions.cpp diff --git a/runtime/JSGlobalObjectFunctions.cpp b/runtime/JSGlobalObjectFunctions.cpp index be160a8..228ed6c 100644 --- a/runtime/JSGlobalObjectFunctions.cpp +++ b/runtime/JSGlobalObjectFunctions.cpp @@ -27,14 +27,17 @@ #include "CallFrame.h" #include "GlobalEvalFunction.h" +#include "Interpreter.h" #include "JSGlobalObject.h" -#include "LiteralParser.h" #include "JSString.h" -#include "Interpreter.h" -#include "Parser.h" -#include "dtoa.h" +#include "JSStringBuilder.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 @@ -52,27 +55,27 @@ static JSValue encode(ExecState* exec, const ArgList& args, const char* doNotEsc { UString str = args.at(0).toString(exec); CString cstr = str.UTF8String(true); - if (!cstr.c_str()) + if (!cstr.data()) return throwError(exec, URIError, "String contained an illegal UTF-16 sequence."); - UString result = ""; - const char* p = cstr.c_str(); - for (size_t k = 0; k < cstr.size(); k++, p++) { + JSStringBuilder builder; + const char* p = cstr.data(); + for (size_t k = 0; k < cstr.length(); 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(tmp); } } - return jsString(exec, result); + return builder.build(exec); } static JSValue decode(ExecState* exec, const ArgList& args, const char* doNotUnescape, bool strict) { - UString result = ""; + JSStringBuilder builder; UString str = args.at(0).toString(exec); int k = 0; int len = str.size(); @@ -106,7 +109,7 @@ static JSValue decode(ExecState* exec, const ArgList& args, const char* doNotUne 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); @@ -131,9 +134,9 @@ static JSValue decode(ExecState* exec, const ArgList& args, const char* doNotUne } } k++; - result.append(c); + builder.append(c); } - return jsString(exec, result); + return builder.build(exec); } bool isStrWhiteSpace(UChar c) @@ -238,6 +241,7 @@ static double parseInt(const UString& s, int radix) } if (number >= mantissaOverflowLowerBound) { + // FIXME: It is incorrect to use UString::ascii() here because it's not thread-safe. if (radix == 10) number = WTF::strtod(s.substr(firstDigitPosition, p - firstDigitPosition).ascii(), 0); else if (radix == 2 || radix == 4 || radix == 8 || radix == 16 || radix == 32) @@ -266,6 +270,8 @@ static double parseFloat(const UString& s) if (length - p >= 2 && data[p] == '0' && (data[p + 1] == 'x' || data[p + 1] == 'X')) return 0; + // FIXME: UString::toDouble will ignore leading ASCII spaces, but we need to ignore + // other StrWhiteSpaceChar values as well. return s.toDouble(true /*tolerant*/, false /* NaN for empty string */); } @@ -286,16 +292,12 @@ JSValue JSC_HOST_CALL globalFuncEval(ExecState* exec, JSObject* function, JSValu if (JSValue parsedObject = preparser.tryLiteralParse()) return parsedObject; - int errLine; - UString errMsg; - - SourceCode source = makeSource(s); - RefPtr evalNode = exec->globalData().parser->parse(exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg); - - 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()); } JSValue JSC_HOST_CALL globalFuncParseInt(ExecState* exec, JSObject*, JSValue, const ArgList& args) @@ -380,32 +382,30 @@ JSValue JSC_HOST_CALL globalFuncEscape(ExecState* exec, JSObject*, JSValue, cons "0123456789" "*+-./@_"; - UString result = ""; - UString s; + JSStringBuilder builder; UString str = args.at(0).toString(exec); const UChar* c = str.data(); - for (int k = 0; k < str.size(); k++, c++) { + for (unsigned k = 0; k < str.size(); k++, c++) { int u = c[0]; if (u > 255) { char tmp[7]; snprintf(tmp, sizeof(tmp), "%%u%04X", u); - s = UString(tmp); + builder.append(tmp); } else if (u != 0 && strchr(do_not_escape, static_cast(u))) - s = UString(c, 1); + builder.append(c, 1); else { char tmp[4]; snprintf(tmp, sizeof(tmp), "%%%02X", u); - s = UString(tmp); + builder.append(tmp); } - result += s; } - return jsString(exec, result); + return builder.build(exec); } JSValue JSC_HOST_CALL globalFuncUnescape(ExecState* exec, JSObject*, JSValue, const ArgList& args) { - UString result = ""; + StringBuilder builder; UString str = args.at(0).toString(exec); int k = 0; int len = str.size(); @@ -424,17 +424,16 @@ JSValue JSC_HOST_CALL globalFuncUnescape(ExecState* exec, JSObject*, JSValue, co k += 2; } k++; - result.append(*c); + builder.append(*c); } - return jsString(exec, result); + return jsString(exec, builder.build()); } #ifndef NDEBUG JSValue JSC_HOST_CALL globalFuncJSCPrint(ExecState* exec, JSObject*, JSValue, const ArgList& args) { - CStringBuffer string; - args.at(0).toString(exec).getCString(string); + CString string = args.at(0).toString(exec).UTF8String(); puts(string.data()); return jsUndefined(); }