[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.17-1283-gcf603cf
barraclough at apple.com
barraclough at apple.com
Tue Jan 5 23:48:39 UTC 2010
The following commit has been merged in the webkit-1.1 branch:
commit 7e78fbceeec05d059a1f08d1e58b0603034ce1e3
Author: barraclough at apple.com <barraclough at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Mon Dec 14 00:27:07 2009 +0000
https://bugs.webkit.org/show_bug.cgi?id=32496
Switch remaining cases of string construction to use StringBuilder.
Builds strings using a vector rather than using string append / addition.
Reviewed by Sam Weinig.
* JavaScriptCore.exp:
* JavaScriptCore.xcodeproj/project.pbxproj:
* runtime/Executable.cpp:
(JSC::FunctionExecutable::paramString):
* runtime/FunctionConstructor.cpp:
(JSC::constructFunction):
* runtime/JSGlobalObjectFunctions.cpp:
(JSC::encode):
(JSC::decode):
(JSC::globalFuncEscape):
(JSC::globalFuncUnescape):
* runtime/JSONObject.cpp:
(JSC::Stringifier::stringify):
(JSC::Stringifier::indent):
* runtime/JSString.h:
* runtime/LiteralParser.cpp:
(JSC::LiteralParser::Lexer::lexString):
* runtime/NumberPrototype.cpp:
(JSC::integerPartNoExp):
(JSC::numberProtoFuncToFixed):
(JSC::numberProtoFuncToPrecision):
* runtime/Operations.h:
(JSC::jsString):
* runtime/StringPrototype.cpp:
(JSC::substituteBackreferencesSlow):
(JSC::substituteBackreferences):
(JSC::stringProtoFuncConcat):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@52075 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 7054897..ef8b1c1 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,39 @@
+2009-12-13 Gavin Barraclough <barraclough at apple.com>
+
+ Reviewed by Sam Weinig.
+
+ https://bugs.webkit.org/show_bug.cgi?id=32496
+ Switch remaining cases of string construction to use StringBuilder.
+ Builds strings using a vector rather than using string append / addition.
+
+ * JavaScriptCore.exp:
+ * JavaScriptCore.xcodeproj/project.pbxproj:
+ * runtime/Executable.cpp:
+ (JSC::FunctionExecutable::paramString):
+ * runtime/FunctionConstructor.cpp:
+ (JSC::constructFunction):
+ * runtime/JSGlobalObjectFunctions.cpp:
+ (JSC::encode):
+ (JSC::decode):
+ (JSC::globalFuncEscape):
+ (JSC::globalFuncUnescape):
+ * runtime/JSONObject.cpp:
+ (JSC::Stringifier::stringify):
+ (JSC::Stringifier::indent):
+ * runtime/JSString.h:
+ * runtime/LiteralParser.cpp:
+ (JSC::LiteralParser::Lexer::lexString):
+ * runtime/NumberPrototype.cpp:
+ (JSC::integerPartNoExp):
+ (JSC::numberProtoFuncToFixed):
+ (JSC::numberProtoFuncToPrecision):
+ * runtime/Operations.h:
+ (JSC::jsString):
+ * runtime/StringPrototype.cpp:
+ (JSC::substituteBackreferencesSlow):
+ (JSC::substituteBackreferences):
+ (JSC::stringProtoFuncConcat):
+
2009-12-08 Jeremy Moskovich <jeremy at chromium.org>
Reviewed by Eric Seidel.
diff --git a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
index e766243..1626e50 100644
--- a/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
+++ b/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
@@ -204,6 +204,7 @@
863B23E00FC6118900703AA4 /* MacroAssemblerCodeRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 863B23DF0FC60E6200703AA4 /* MacroAssemblerCodeRef.h */; settings = {ATTRIBUTES = (Private, ); }; };
869083150E6518D7000D36ED /* WREC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 869083130E6518D7000D36ED /* WREC.cpp */; };
869083160E6518D7000D36ED /* WREC.h in Headers */ = {isa = PBXBuildFile; fileRef = 869083140E6518D7000D36ED /* WREC.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 8698B86910D44D9400D8D01B /* StringBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 8698B86810D44D9400D8D01B /* StringBuilder.h */; };
869EBCB70E8C6D4A008722CC /* ResultType.h in Headers */ = {isa = PBXBuildFile; fileRef = 869EBCB60E8C6D4A008722CC /* ResultType.h */; settings = {ATTRIBUTES = (Private, ); }; };
86A90ED00EE7D51F00AB350D /* JITArithmetic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86A90ECF0EE7D51F00AB350D /* JITArithmetic.cpp */; };
86ADD1450FDDEA980006EEC2 /* ARMv7Assembler.h in Headers */ = {isa = PBXBuildFile; fileRef = 86ADD1430FDDEA980006EEC2 /* ARMv7Assembler.h */; };
@@ -728,6 +729,7 @@
863B23DF0FC60E6200703AA4 /* MacroAssemblerCodeRef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerCodeRef.h; sourceTree = "<group>"; };
869083130E6518D7000D36ED /* WREC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WREC.cpp; sourceTree = "<group>"; };
869083140E6518D7000D36ED /* WREC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WREC.h; sourceTree = "<group>"; };
+ 8698B86810D44D9400D8D01B /* StringBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StringBuilder.h; sourceTree = "<group>"; };
869EBCB60E8C6D4A008722CC /* ResultType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResultType.h; sourceTree = "<group>"; };
86A90ECF0EE7D51F00AB350D /* JITArithmetic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JITArithmetic.cpp; sourceTree = "<group>"; };
86ADD1430FDDEA980006EEC2 /* ARMv7Assembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARMv7Assembler.h; sourceTree = "<group>"; };
@@ -1530,6 +1532,8 @@
14F252560D08DD8D004ECFFF /* JSVariableObject.h */,
65C7A1710A8EAACB00FA37EA /* JSWrapperObject.cpp */,
65C7A1720A8EAACB00FA37EA /* JSWrapperObject.h */,
+ A7C2216810C745E000F97913 /* JSZombie.h */,
+ A7C2216B10C7469C00F97913 /* JSZombie.cpp */,
A7E2EA6A0FB460CF00601F06 /* LiteralParser.cpp */,
A7E2EA690FB460CF00601F06 /* LiteralParser.h */,
F692A8680255597D01FF60F7 /* Lookup.cpp */,
@@ -1582,6 +1586,7 @@
7E2C6C980D31C6B6002D44E2 /* ScopeChainMark.h */,
93303FE80E6A72B500786E6A /* SmallStrings.cpp */,
93303FEA0E6A72C000786E6A /* SmallStrings.h */,
+ 8698B86810D44D9400D8D01B /* StringBuilder.h */,
BC18C3C00E16EE3300B34460 /* StringConstructor.cpp */,
BC18C3C10E16EE3300B34460 /* StringConstructor.h */,
BC18C3C20E16EE3300B34460 /* StringObject.cpp */,
@@ -1602,8 +1607,6 @@
F692A8850255597D01FF60F7 /* UString.cpp */,
F692A8860255597D01FF60F7 /* UString.h */,
1420BE7A10AA6DDB00F455D2 /* WeakRandom.h */,
- A7C2216810C745E000F97913 /* JSZombie.h */,
- A7C2216B10C7469C00F97913 /* JSZombie.cpp */,
);
path = runtime;
sourceTree = "<group>";
@@ -2014,6 +2017,7 @@
148CD1D8108CF902008163C6 /* JSContextRefPrivate.h in Headers */,
14A1563210966365006FA260 /* DateInstanceCache.h in Headers */,
1420BE7B10AA6DDB00F455D2 /* WeakRandom.h in Headers */,
+ 8698B86910D44D9400D8D01B /* StringBuilder.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/JavaScriptCore/runtime/Executable.cpp b/JavaScriptCore/runtime/Executable.cpp
index 7586746..bc18cc9 100644
--- a/JavaScriptCore/runtime/Executable.cpp
+++ b/JavaScriptCore/runtime/Executable.cpp
@@ -30,6 +30,7 @@
#include "CodeBlock.h"
#include "JIT.h"
#include "Parser.h"
+#include "StringBuilder.h"
#include "Vector.h"
namespace JSC {
@@ -265,14 +266,13 @@ PassRefPtr<FunctionExecutable> FunctionExecutable::fromGlobalCode(const Identifi
UString FunctionExecutable::paramString() const
{
FunctionParameters& parameters = *m_parameters;
- UString s("");
+ StringBuilder builder;
for (size_t pos = 0; pos < parameters.size(); ++pos) {
- if (!s.isEmpty())
- s += ", ";
- s += parameters[pos].ustring();
+ if (!builder.isEmpty())
+ builder.append(", ");
+ builder.append(parameters[pos].ustring());
}
-
- return s;
+ return builder.release();
}
};
diff --git a/JavaScriptCore/runtime/FunctionConstructor.cpp b/JavaScriptCore/runtime/FunctionConstructor.cpp
index 9d88400..9d55dd1 100644
--- a/JavaScriptCore/runtime/FunctionConstructor.cpp
+++ b/JavaScriptCore/runtime/FunctionConstructor.cpp
@@ -21,14 +21,15 @@
#include "config.h"
#include "FunctionConstructor.h"
+#include "Debugger.h"
#include "FunctionPrototype.h"
#include "JSFunction.h"
#include "JSGlobalObject.h"
#include "JSString.h"
-#include "Parser.h"
-#include "Debugger.h"
#include "Lexer.h"
#include "Nodes.h"
+#include "Parser.h"
+#include "StringBuilder.h"
namespace JSC {
@@ -76,12 +77,19 @@ JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifi
if (args.isEmpty())
program = "(function() { \n})";
else if (args.size() == 1)
- program = "(function() { " + args.at(0).toString(exec) + "\n})";
+ program = makeString("(function() { ", args.at(0).toString(exec), "\n})");
else {
- program = "(function(" + args.at(0).toString(exec);
- for (size_t i = 1; i < args.size() - 1; i++)
- program += "," + args.at(i).toString(exec);
- program += ") { " + args.at(args.size() - 1).toString(exec) + "\n})";
+ StringBuilder builder;
+ builder.append("(function(");
+ builder.append(args.at(0).toString(exec));
+ for (size_t i = 1; i < args.size() - 1; i++) {
+ builder.append(",");
+ builder.append(args.at(i).toString(exec));
+ }
+ builder.append(") { ");
+ builder.append(args.at(args.size() - 1).toString(exec));
+ builder.append("\n})");
+ program = builder.release();
}
int errLine;
diff --git a/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp b/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
index dc32718..b0a68d5 100644
--- a/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
+++ b/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
@@ -27,14 +27,15 @@
#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 "Lexer.h"
+#include "LiteralParser.h"
#include "Nodes.h"
+#include "Parser.h"
+#include "StringBuilder.h"
+#include "dtoa.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -55,24 +56,24 @@ static JSValue encode(ExecState* exec, const ArgList& args, const char* doNotEsc
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];
- sprintf(tmp, "%%%02X", static_cast<unsigned char>(c));
- result += tmp;
+ snprintf(tmp, 4, "%%%02X", static_cast<unsigned char>(c));
+ builder.append((const char*)tmp);
}
}
- return jsString(exec, result);
+ return jsString(exec, builder.release());
}
static JSValue decode(ExecState* exec, const ArgList& args, const char* doNotUnescape, bool strict)
{
- UString result = "";
+ StringBuilder builder;
UString str = args.at(0).toString(exec);
int k = 0;
int len = str.size();
@@ -106,7 +107,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<UChar>(0xD800 | ((character - 0x10000) >> 10)));
+ builder.append(static_cast<UChar>(0xD800 | ((character - 0x10000) >> 10)));
u = static_cast<UChar>(0xDC00 | ((character - 0x10000) & 0x3FF));
} else
u = static_cast<UChar>(character);
@@ -131,9 +132,9 @@ static JSValue decode(ExecState* exec, const ArgList& args, const char* doNotUne
}
}
k++;
- result.append(c);
+ builder.append(c);
}
- return jsString(exec, result);
+ return jsString(exec, builder.release());
}
bool isStrWhiteSpace(UChar c)
@@ -376,7 +377,7 @@ JSValue JSC_HOST_CALL globalFuncEscape(ExecState* exec, JSObject*, JSValue, cons
"0123456789"
"*+-./@_";
- UString result = "";
+ StringBuilder builder;
UString s;
UString str = args.at(0).toString(exec);
const UChar* c = str.data();
@@ -393,15 +394,15 @@ JSValue JSC_HOST_CALL globalFuncEscape(ExecState* exec, JSObject*, JSValue, cons
sprintf(tmp, "%%%02X", u);
s = UString(tmp);
}
- result += s;
+ builder.append(s);
}
- return jsString(exec, result);
+ return jsString(exec, builder.release());
}
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();
@@ -420,10 +421,10 @@ 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.release());
}
#ifndef NDEBUG
diff --git a/JavaScriptCore/runtime/JSONObject.cpp b/JavaScriptCore/runtime/JSONObject.cpp
index cc7f6d9..f28e70e 100644
--- a/JavaScriptCore/runtime/JSONObject.cpp
+++ b/JavaScriptCore/runtime/JSONObject.cpp
@@ -32,6 +32,7 @@
#include "JSArray.h"
#include "LiteralParser.h"
#include "PropertyNameArray.h"
+#include "StringBuilder.h"
#include <wtf/MathExtras.h>
namespace JSC {
@@ -70,24 +71,6 @@ public:
void markAggregate(MarkStack&);
private:
- class StringBuilder : public Vector<UChar> {
- public:
- using Vector<UChar>::append;
-
- inline void append(const char* str)
- {
- size_t len = strlen(str);
- reserveCapacity(size() + len);
- for (size_t i = 0; i < len; i++)
- Vector<UChar>::append(str[i]);
- }
-
- inline void append(const UString& str)
- {
- append(str.data(), str.size());
- }
- };
-
class Holder {
public:
Holder(JSObject*);
@@ -285,9 +268,7 @@ JSValue Stringifier::stringify(JSValue value)
if (m_exec->hadException())
return jsNull();
- result.shrinkToFit();
- size_t length = result.size();
- return jsString(m_exec, UString(result.releaseBuffer(), length, false));
+ return jsString(m_exec, result.release());
}
void Stringifier::appendQuotedString(StringBuilder& builder, const UString& value)
@@ -477,7 +458,7 @@ inline void Stringifier::indent()
// Use a single shared string, m_repeatedGap, so we don't keep allocating new ones as we indent and unindent.
int newSize = m_indent.size() + m_gap.size();
if (newSize > m_repeatedGap.size())
- m_repeatedGap.append(m_gap);
+ m_repeatedGap = makeString(m_repeatedGap, m_gap);
ASSERT(newSize <= m_repeatedGap.size());
m_indent = m_repeatedGap.substr(0, newSize);
}
diff --git a/JavaScriptCore/runtime/JSString.h b/JavaScriptCore/runtime/JSString.h
index 33e60ab..c423814 100644
--- a/JavaScriptCore/runtime/JSString.h
+++ b/JavaScriptCore/runtime/JSString.h
@@ -345,6 +345,7 @@ namespace JSC {
friend JSValue jsString(ExecState* exec, const UString& u1, JSString* s2);
friend JSValue jsString(ExecState* exec, JSString* s1, const UString& u2);
friend JSValue jsString(ExecState* exec, Register* strings, unsigned count);
+ friend JSValue jsString(ExecState* exec, JSValue thisValue, const ArgList& args);
};
JSString* asString(JSValue);
diff --git a/JavaScriptCore/runtime/LiteralParser.cpp b/JavaScriptCore/runtime/LiteralParser.cpp
index d242282..aa1e5ed 100644
--- a/JavaScriptCore/runtime/LiteralParser.cpp
+++ b/JavaScriptCore/runtime/LiteralParser.cpp
@@ -29,6 +29,7 @@
#include "JSArray.h"
#include "JSString.h"
#include "Lexer.h"
+#include "StringBuilder.h"
#include <wtf/ASCIICType.h>
#include <wtf/dtoa.h>
@@ -134,48 +135,48 @@ template <LiteralParser::ParserMode mode> inline LiteralParser::TokenType Litera
{
++m_ptr;
const UChar* runStart;
- token.stringToken = UString();
+ StringBuilder builder;
do {
runStart = m_ptr;
while (m_ptr < m_end && isSafeStringCharacter<mode>(*m_ptr))
++m_ptr;
if (runStart < m_ptr)
- token.stringToken.append(runStart, m_ptr - runStart);
+ builder.append(runStart, m_ptr - runStart);
if ((mode == StrictJSON) && m_ptr < m_end && *m_ptr == '\\') {
++m_ptr;
if (m_ptr >= m_end)
return TokError;
switch (*m_ptr) {
case '"':
- token.stringToken.append('"');
+ builder.append('"');
m_ptr++;
break;
case '\\':
- token.stringToken.append('\\');
+ builder.append('\\');
m_ptr++;
break;
case '/':
- token.stringToken.append('/');
+ builder.append('/');
m_ptr++;
break;
case 'b':
- token.stringToken.append('\b');
+ builder.append('\b');
m_ptr++;
break;
case 'f':
- token.stringToken.append('\f');
+ builder.append('\f');
m_ptr++;
break;
case 'n':
- token.stringToken.append('\n');
+ builder.append('\n');
m_ptr++;
break;
case 'r':
- token.stringToken.append('\r');
+ builder.append('\r');
m_ptr++;
break;
case 't':
- token.stringToken.append('\t');
+ builder.append('\t');
m_ptr++;
break;
@@ -186,7 +187,7 @@ template <LiteralParser::ParserMode mode> inline LiteralParser::TokenType Litera
if (!isASCIIHexDigit(m_ptr[i]))
return TokError;
}
- token.stringToken.append(JSC::Lexer::convertUnicode(m_ptr[1], m_ptr[2], m_ptr[3], m_ptr[4]));
+ builder.append(JSC::Lexer::convertUnicode(m_ptr[1], m_ptr[2], m_ptr[3], m_ptr[4]));
m_ptr += 5;
break;
@@ -199,6 +200,7 @@ template <LiteralParser::ParserMode mode> inline LiteralParser::TokenType Litera
if (m_ptr >= m_end || *m_ptr != '"')
return TokError;
+ token.stringToken = builder.release();
token.type = TokString;
token.end = ++m_ptr;
return TokString;
diff --git a/JavaScriptCore/runtime/NumberPrototype.cpp b/JavaScriptCore/runtime/NumberPrototype.cpp
index df31404..67210fa 100644
--- a/JavaScriptCore/runtime/NumberPrototype.cpp
+++ b/JavaScriptCore/runtime/NumberPrototype.cpp
@@ -25,9 +25,10 @@
#include "Error.h"
#include "JSFunction.h"
#include "JSString.h"
+#include "Operations.h"
#include "PrototypeFunction.h"
+#include "StringBuilder.h"
#include "dtoa.h"
-#include "Operations.h"
#include <wtf/Assertions.h>
#include <wtf/MathExtras.h>
#include <wtf/Vector.h>
@@ -73,11 +74,12 @@ static UString integerPartNoExp(double d)
bool resultIsInfOrNan = (decimalPoint == 9999);
size_t length = strlen(result);
- UString str = sign ? "-" : "";
+ StringBuilder builder;
+ builder.append(sign ? "-" : "");
if (resultIsInfOrNan)
- str += result;
+ builder.append((const char*)result);
else if (decimalPoint <= 0)
- str += "0";
+ builder.append("0");
else {
Vector<char, 1024> buf(decimalPoint + 1);
@@ -89,10 +91,10 @@ static UString integerPartNoExp(double d)
strncpy(buf.data(), result, decimalPoint);
buf[decimalPoint] = '\0';
- str.append(buf.data());
+ builder.append((const char*)(buf.data()));
}
- return str;
+ return builder.release();
}
static UString charSequence(char c, int count)
@@ -236,13 +238,16 @@ JSValue JSC_HOST_CALL numberProtoFuncToFixed(ExecState* exec, JSObject*, JSValue
UString s;
if (x < 0) {
- s.append('-');
+ s = "-";
x = -x;
- } else if (x == -0.0)
- x = 0;
+ } else {
+ s = "";
+ if (x == -0.0)
+ x = 0;
+ }
if (x >= pow(10.0, 21.0))
- return jsString(exec, s + UString::from(x));
+ return jsString(exec, makeString(s, UString::from(x)));
const double tenToTheF = pow(10.0, f);
double n = floor(x * tenToTheF);
@@ -253,17 +258,19 @@ JSValue JSC_HOST_CALL numberProtoFuncToFixed(ExecState* exec, JSObject*, JSValue
int k = m.size();
if (k <= f) {
- UString z;
+ StringBuilder z;
for (int i = 0; i < f + 1 - k; i++)
z.append('0');
- m = z + m;
+ z.append(m);
+ m = z.release();
k = f + 1;
ASSERT(k == m.size());
}
int kMinusf = k - f;
+
if (kMinusf < m.size())
- return jsString(exec, s + m.substr(0, kMinusf) + "." + m.substr(kMinusf));
- return jsString(exec, s + m.substr(0, kMinusf));
+ return jsString(exec, makeString(s, m.substr(0, kMinusf), ".", m.substr(kMinusf)));
+ return jsString(exec, makeString(s, m.substr(0, kMinusf)));
}
static void fractionalPartToString(char* buf, int& i, const char* result, int resultLength, int fractionalDigits)
@@ -391,7 +398,8 @@ JSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState* exec, JSObject*, JSV
if (x < 0) {
s = "-";
x = -x;
- }
+ } else
+ s = "";
if (!(doublePrecision >= 1 && doublePrecision <= 21)) // true for NaN
return throwError(exec, RangeError, "toPrecision() argument must be between 1 and 21");
@@ -422,10 +430,10 @@ JSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState* exec, JSObject*, JSV
m = integerPartNoExp(n);
if (e < -6 || e >= precision) {
if (m.size() > 1)
- m = m.substr(0, 1) + "." + m.substr(1);
+ m = makeString(m.substr(0, 1), ".", m.substr(1));
if (e >= 0)
- return jsNontrivialString(exec, s + m + "e+" + UString::from(e));
- return jsNontrivialString(exec, s + m + "e-" + UString::from(-e));
+ return jsNontrivialString(exec, makeString(s, m, "e+", UString::from(e)));
+ return jsNontrivialString(exec, makeString(s, m, "e-", UString::from(-e)));
}
} else {
m = charSequence('0', precision);
@@ -433,13 +441,13 @@ JSValue JSC_HOST_CALL numberProtoFuncToPrecision(ExecState* exec, JSObject*, JSV
}
if (e == precision - 1)
- return jsString(exec, s + m);
+ return jsString(exec, makeString(s, m));
if (e >= 0) {
if (e + 1 < m.size())
- return jsString(exec, s + m.substr(0, e + 1) + "." + m.substr(e + 1));
- return jsString(exec, s + m);
+ return jsString(exec, makeString(s, m.substr(0, e + 1), ".", m.substr(e + 1)));
+ return jsString(exec, makeString(s, m));
}
- return jsNontrivialString(exec, s + "0." + charSequence('0', -(e + 1)) + m);
+ return jsNontrivialString(exec, makeString(s, "0.", charSequence('0', -(e + 1)), m));
}
} // namespace JSC
diff --git a/JavaScriptCore/runtime/Operations.h b/JavaScriptCore/runtime/Operations.h
index 2d1127b..a56893c 100644
--- a/JavaScriptCore/runtime/Operations.h
+++ b/JavaScriptCore/runtime/Operations.h
@@ -128,6 +128,43 @@ namespace JSC {
return new (globalData) JSString(globalData, rope.release());
}
+ ALWAYS_INLINE JSValue jsString(ExecState* exec, JSValue thisValue, const ArgList& args)
+ {
+ unsigned ropeLength = 0;
+ if (LIKELY(thisValue.isString()))
+ ropeLength += asString(thisValue)->ropeLength();
+ else
+ ++ropeLength;
+ for (unsigned i = 0; i < args.size(); ++i) {
+ JSValue v = args.at(i);
+ if (LIKELY(v.isString()))
+ ropeLength += asString(v)->ropeLength();
+ else
+ ++ropeLength;
+ }
+
+ RefPtr<JSString::Rope> rope = JSString::Rope::createOrNull(ropeLength);
+ if (UNLIKELY(!rope))
+ return throwOutOfMemoryError(exec);
+
+ unsigned index = 0;
+ if (LIKELY(thisValue.isString()))
+ rope->append(index, asString(thisValue));
+ else
+ rope->append(index, thisValue.toString(exec));
+ for (unsigned i = 0; i < args.size(); ++i) {
+ JSValue v = args.at(i);
+ if (LIKELY(v.isString()))
+ rope->append(index, asString(v));
+ else
+ rope->append(index, v.toString(exec));
+ }
+ ASSERT(index == ropeLength);
+
+ JSGlobalData* globalData = &exec->globalData();
+ return new (globalData) JSString(globalData, rope.release());
+ }
+
// ECMA 11.9.3
inline bool JSValue::equal(ExecState* exec, JSValue v1, JSValue v2)
{
diff --git a/JavaScriptCore/runtime/StringBuilder.h b/JavaScriptCore/runtime/StringBuilder.h
new file mode 100644
index 0000000..6de2c3f
--- /dev/null
+++ b/JavaScriptCore/runtime/StringBuilder.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef StringBuilder_h
+#define StringBuilder_h
+
+#include <wtf/Vector.h>
+
+namespace JSC {
+
+class StringBuilder {
+public:
+ void append(const UChar u)
+ {
+ buffer.append(u);
+ }
+
+ void append(const char* str)
+ {
+ buffer.append(str, strlen(str));
+ }
+
+ void append(const char* str, size_t len)
+ {
+ buffer.reserveCapacity(buffer.size() + len);
+ for (size_t i = 0; i < len; i++)
+ buffer.append(static_cast<unsigned char>(str[i]));
+ }
+
+ void append(const UChar* str, size_t len)
+ {
+ buffer.append(str, len);
+ }
+
+ void append(const UString& str)
+ {
+ buffer.append(str.data(), str.size());
+ }
+
+ bool isEmpty() { return buffer.isEmpty(); }
+ void reserveCapacity(size_t newCapacity) { buffer.reserveCapacity(newCapacity); }
+ void resize(size_t size) { buffer.resize(size); }
+ size_t size() const { return buffer.size(); }
+
+ UChar operator[](size_t i) { return buffer.at(i); }
+ const UChar operator[](size_t i) const { return buffer.at(i); }
+
+ UString release()
+ {
+ buffer.shrinkToFit();
+ size_t length = buffer.size();
+ return UString(buffer.releaseBuffer(), length, false);
+ }
+
+private:
+ Vector<UChar, 64> buffer;
+};
+
+}
+
+#endif
diff --git a/JavaScriptCore/runtime/StringPrototype.cpp b/JavaScriptCore/runtime/StringPrototype.cpp
index be5a671..5f470fd 100644
--- a/JavaScriptCore/runtime/StringPrototype.cpp
+++ b/JavaScriptCore/runtime/StringPrototype.cpp
@@ -29,6 +29,7 @@
#include "JSArray.h"
#include "JSFunction.h"
#include "ObjectPrototype.h"
+#include "Operations.h"
#include "PropertyNameArray.h"
#include "RegExpConstructor.h"
#include "RegExpObject.h"
@@ -148,12 +149,11 @@ bool StringPrototype::getOwnPropertyDescriptor(ExecState* exec, const Identifier
// ------------------------------ Functions --------------------------
-static inline UString substituteBackreferences(const UString& replacement, const UString& source, const int* ovector, RegExp* reg)
+static NEVER_INLINE UString substituteBackreferencesSlow(const UString& replacement, const UString& source, const int* ovector, RegExp* reg, int i)
{
- UString substitutedReplacement;
+ Vector<UChar> substitutedReplacement;
int offset = 0;
- int i = -1;
- while ((i = replacement.find('$', i + 1)) != -1) {
+ do {
if (i + 1 == replacement.size())
break;
@@ -205,15 +205,22 @@ static inline UString substituteBackreferences(const UString& replacement, const
i += 1 + advance;
offset = i + 1;
substitutedReplacement.append(source.data() + backrefStart, backrefLength);
- }
-
- if (!offset)
- return replacement;
+ } while ((i = replacement.find('$', i + 1)) != -1);
if (replacement.size() - offset)
substitutedReplacement.append(replacement.data() + offset, replacement.size() - offset);
- return substitutedReplacement;
+ substitutedReplacement.shrinkToFit();
+ unsigned size = substitutedReplacement.size();
+ return UString(substitutedReplacement.releaseBuffer(), size, false);
+}
+
+static inline UString substituteBackreferences(const UString& replacement, const UString& source, const int* ovector, RegExp* reg)
+{
+ int i = replacement.find('$', 0);
+ if (UNLIKELY(i != -1))
+ return substituteBackreferencesSlow(replacement, source, ovector, reg, i);
+ return replacement;
}
static inline int localeCompare(const UString& a, const UString& b)
@@ -423,12 +430,14 @@ JSValue JSC_HOST_CALL stringProtoFuncCharCodeAt(ExecState* exec, JSObject*, JSVa
JSValue JSC_HOST_CALL stringProtoFuncConcat(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
- UString s = thisValue.toThisString(exec);
+ if (thisValue.isString() && (args.size() == 1)) {
+ JSValue v = args.at(0);
+ return v.isString()
+ ? jsString(exec, asString(thisValue), asString(v))
+ : jsString(exec, asString(thisValue), v.toString(exec));
+ }
- ArgList::const_iterator end = args.end();
- for (ArgList::const_iterator it = args.begin(); it != end; ++it)
- s += (*it).toString(exec);
- return jsString(exec, s);
+ return jsString(exec, thisValue, args);
}
JSValue JSC_HOST_CALL stringProtoFuncIndexOf(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
diff --git a/JavaScriptCore/runtime/UString.h b/JavaScriptCore/runtime/UString.h
index 9c2433b..ec9c211 100644
--- a/JavaScriptCore/runtime/UString.h
+++ b/JavaScriptCore/runtime/UString.h
@@ -543,8 +543,7 @@ namespace JSC {
};
template<>
- class StringTypeAdapter<char*>
- {
+ class StringTypeAdapter<char*> {
public:
StringTypeAdapter<char*>(char* buffer)
: m_buffer((unsigned char*)buffer)
@@ -566,8 +565,7 @@ namespace JSC {
};
template<>
- class StringTypeAdapter<const char*>
- {
+ class StringTypeAdapter<const char*> {
public:
StringTypeAdapter<const char*>(const char* buffer)
: m_buffer((unsigned char*)buffer)
@@ -589,8 +587,7 @@ namespace JSC {
};
template<>
- class StringTypeAdapter<UString>
- {
+ class StringTypeAdapter<UString> {
public:
StringTypeAdapter<UString>(UString& string)
: m_data(string.data())
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list