Commit e82d3905 authored by barraclough@apple.com's avatar barraclough@apple.com

https://bugs.webkit.org/show_bug.cgi?id=32454

Refactor construction of simple strings to avoid string concatenation.

Reviewed by Oliver Hunt.

Building strings through concatenation has a memory and performance cost -
a memory cost since we must over-allocate the buffer to leave space to append
into, and performance in that the string may still require reallocation (and
thus copying during construction).  Instead move the full construction to
within a single function call (makeString), so that the arguments' lengths
can be calculated and an appropriate sized buffer allocated before copying
any characters.

~No performance change (~2% progression on date tests).

* bytecode/CodeBlock.cpp:
(JSC::escapeQuotes):
(JSC::valueToSourceString):
(JSC::constantName):
(JSC::idName):
(JSC::CodeBlock::registerName):
(JSC::regexpToSourceString):
(JSC::regexpName):
* bytecompiler/NodesCodegen.cpp:
(JSC::substitute):
* profiler/Profiler.cpp:
(JSC::Profiler::createCallIdentifier):
* runtime/DateConstructor.cpp:
(JSC::callDate):
* runtime/DateConversion.cpp:
(JSC::formatDate):
(JSC::formatDateUTCVariant):
(JSC::formatTime):
(JSC::formatTimeUTC):
* runtime/DateConversion.h:
(JSC::):
* runtime/DatePrototype.cpp:
(JSC::dateProtoFuncToString):
(JSC::dateProtoFuncToUTCString):
(JSC::dateProtoFuncToDateString):
(JSC::dateProtoFuncToTimeString):
(JSC::dateProtoFuncToGMTString):
* runtime/ErrorPrototype.cpp:
(JSC::errorProtoFuncToString):
* runtime/ExceptionHelpers.cpp:
(JSC::createUndefinedVariableError):
(JSC::createErrorMessage):
(JSC::createInvalidParamError):
* runtime/FunctionPrototype.cpp:
(JSC::insertSemicolonIfNeeded):
(JSC::functionProtoFuncToString):
* runtime/ObjectPrototype.cpp:
(JSC::objectProtoFuncToString):
* runtime/RegExpConstructor.cpp:
(JSC::constructRegExp):
* runtime/RegExpObject.cpp:
(JSC::RegExpObject::match):
* runtime/RegExpPrototype.cpp:
(JSC::regExpProtoFuncCompile):
(JSC::regExpProtoFuncToString):
* runtime/StringPrototype.cpp:
(JSC::stringProtoFuncBig):
(JSC::stringProtoFuncSmall):
(JSC::stringProtoFuncBlink):
(JSC::stringProtoFuncBold):
(JSC::stringProtoFuncFixed):
(JSC::stringProtoFuncItalics):
(JSC::stringProtoFuncStrike):
(JSC::stringProtoFuncSub):
(JSC::stringProtoFuncSup):
(JSC::stringProtoFuncFontcolor):
(JSC::stringProtoFuncFontsize):
(JSC::stringProtoFuncAnchor):
* runtime/UString.h:
(JSC::):
(JSC::makeString):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@52028 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 401fe2b0
2009-12-11 Gavin Barraclough <barraclough@apple.com>
Reviewed by Oliver Hunt.
https://bugs.webkit.org/show_bug.cgi?id=32454
Refactor construction of simple strings to avoid string concatenation.
Building strings through concatenation has a memory and performance cost -
a memory cost since we must over-allocate the buffer to leave space to append
into, and performance in that the string may still require reallocation (and
thus copying during construction). Instead move the full construction to
within a single function call (makeString), so that the arguments' lengths
can be calculated and an appropriate sized buffer allocated before copying
any characters.
~No performance change (~2% progression on date tests).
* bytecode/CodeBlock.cpp:
(JSC::escapeQuotes):
(JSC::valueToSourceString):
(JSC::constantName):
(JSC::idName):
(JSC::CodeBlock::registerName):
(JSC::regexpToSourceString):
(JSC::regexpName):
* bytecompiler/NodesCodegen.cpp:
(JSC::substitute):
* profiler/Profiler.cpp:
(JSC::Profiler::createCallIdentifier):
* runtime/DateConstructor.cpp:
(JSC::callDate):
* runtime/DateConversion.cpp:
(JSC::formatDate):
(JSC::formatDateUTCVariant):
(JSC::formatTime):
(JSC::formatTimeUTC):
* runtime/DateConversion.h:
(JSC::):
* runtime/DatePrototype.cpp:
(JSC::dateProtoFuncToString):
(JSC::dateProtoFuncToUTCString):
(JSC::dateProtoFuncToDateString):
(JSC::dateProtoFuncToTimeString):
(JSC::dateProtoFuncToGMTString):
* runtime/ErrorPrototype.cpp:
(JSC::errorProtoFuncToString):
* runtime/ExceptionHelpers.cpp:
(JSC::createUndefinedVariableError):
(JSC::createErrorMessage):
(JSC::createInvalidParamError):
* runtime/FunctionPrototype.cpp:
(JSC::insertSemicolonIfNeeded):
(JSC::functionProtoFuncToString):
* runtime/ObjectPrototype.cpp:
(JSC::objectProtoFuncToString):
* runtime/RegExpConstructor.cpp:
(JSC::constructRegExp):
* runtime/RegExpObject.cpp:
(JSC::RegExpObject::match):
* runtime/RegExpPrototype.cpp:
(JSC::regExpProtoFuncCompile):
(JSC::regExpProtoFuncToString):
* runtime/StringPrototype.cpp:
(JSC::stringProtoFuncBig):
(JSC::stringProtoFuncSmall):
(JSC::stringProtoFuncBlink):
(JSC::stringProtoFuncBold):
(JSC::stringProtoFuncFixed):
(JSC::stringProtoFuncItalics):
(JSC::stringProtoFuncStrike):
(JSC::stringProtoFuncSub):
(JSC::stringProtoFuncSup):
(JSC::stringProtoFuncFontcolor):
(JSC::stringProtoFuncFontsize):
(JSC::stringProtoFuncAnchor):
* runtime/UString.h:
(JSC::):
(JSC::makeString):
2009-12-10 Gavin Barraclough <barraclough@apple.com>
Reviewed by Oliver Hunt.
......
......@@ -51,7 +51,7 @@ static UString escapeQuotes(const UString& str)
UString result = str;
int pos = 0;
while ((pos = result.find('\"', pos)) >= 0) {
result = result.substr(0, pos) + "\"\\\"\"" + result.substr(pos + 1);
result = makeString(result.substr(0, pos), "\"\\\"\"", result.substr(pos + 1));
pos += 4;
}
return result;
......@@ -62,23 +62,20 @@ static UString valueToSourceString(ExecState* exec, JSValue val)
if (!val)
return "0";
if (val.isString()) {
UString result("\"");
result += escapeQuotes(val.toString(exec)) + "\"";
return result;
}
if (val.isString())
return makeString("\"", escapeQuotes(val.toString(exec)), "\"");
return val.toString(exec);
}
static CString constantName(ExecState* exec, int k, JSValue value)
{
return (valueToSourceString(exec, value) + "(@k" + UString::from(k - FirstConstantRegisterIndex) + ")").UTF8String();
return makeString(valueToSourceString(exec, value), "(@k", UString::from(k - FirstConstantRegisterIndex), ")").UTF8String();
}
static CString idName(int id0, const Identifier& ident)
{
return (ident.ustring() + "(@id" + UString::from(id0) +")").UTF8String();
return makeString(ident.ustring(), "(@id", UString::from(id0), ")").UTF8String();
}
CString CodeBlock::registerName(ExecState* exec, int r) const
......@@ -89,25 +86,26 @@ CString CodeBlock::registerName(ExecState* exec, int r) const
if (isConstantRegisterIndex(r))
return constantName(exec, r, getConstant(r));
return (UString("r") + UString::from(r)).UTF8String();
return makeString("r", UString::from(r)).UTF8String();
}
static UString regexpToSourceString(RegExp* regExp)
{
UString pattern = UString("/") + regExp->pattern() + "/";
char postfix[5] = { '/', 0, 0, 0, 0 };
int index = 1;
if (regExp->global())
pattern += "g";
postfix[index++] = 'g';
if (regExp->ignoreCase())
pattern += "i";
postfix[index++] = 'i';
if (regExp->multiline())
pattern += "m";
postfix[index] = 'm';
return pattern;
return makeString("/", regExp->pattern(), postfix);
}
static CString regexpName(int re, RegExp* regexp)
{
return (regexpToSourceString(regexp) + "(@re" + UString::from(re) + ")").UTF8String();
return makeString(regexpToSourceString(regexp), "(@re", UString::from(re), ")").UTF8String();
}
static UString pointerToSourceString(void* p)
......
......@@ -78,10 +78,7 @@ static void substitute(UString& string, const UString& substring)
{
int position = string.find("%s");
ASSERT(position != -1);
UString newString = string.substr(0, position);
newString.append(substring);
newString.append(string.substr(position + 2));
string = newString;
string = makeString(string.substr(0, position), substring, string.substr(position + 2));
}
RegisterID* ThrowableExpressionData::emitThrowError(BytecodeGenerator& generator, ErrorType type, const char* message)
......
......@@ -148,7 +148,7 @@ CallIdentifier Profiler::createCallIdentifier(ExecState* exec, JSValue functionV
}
if (asObject(functionValue)->inherits(&InternalFunction::info))
return CallIdentifier(static_cast<InternalFunction*>(asObject(functionValue))->name(exec), defaultSourceURL, defaultLineNumber);
return CallIdentifier("(" + asObject(functionValue)->className() + " object)", defaultSourceURL, defaultLineNumber);
return CallIdentifier(makeString("(", asObject(functionValue)->className(), " object)"), defaultSourceURL, defaultLineNumber);
}
CallIdentifier createCallIdentifierFromFunctionImp(ExecState* exec, JSFunction* function)
......
......@@ -133,7 +133,11 @@ static JSValue JSC_HOST_CALL callDate(ExecState* exec, JSObject*, JSValue, const
tm localTM;
getLocalTime(&localTime, &localTM);
GregorianDateTime ts(exec, localTM);
return jsNontrivialString(exec, formatDate(ts) + " " + formatTime(ts));
DateConversionBuffer date;
DateConversionBuffer time;
formatDate(ts, date);
formatTime(ts, time);
return jsNontrivialString(exec, makeString(date, " ", time));
}
CallType DateConstructor::getCallData(CallData& callData)
......
......@@ -62,49 +62,41 @@ double parseDate(ExecState* exec, const UString &date)
return value;
}
UString formatDate(const GregorianDateTime &t)
void formatDate(const GregorianDateTime &t, DateConversionBuffer& buffer)
{
char buffer[100];
snprintf(buffer, sizeof(buffer), "%s %s %02d %04d",
snprintf(buffer, DateConversionBufferSize, "%s %s %02d %04d",
weekdayName[(t.weekDay + 6) % 7],
monthName[t.month], t.monthDay, t.year + 1900);
return buffer;
}
UString formatDateUTCVariant(const GregorianDateTime &t)
void formatDateUTCVariant(const GregorianDateTime &t, DateConversionBuffer& buffer)
{
char buffer[100];
snprintf(buffer, sizeof(buffer), "%s, %02d %s %04d",
snprintf(buffer, DateConversionBufferSize, "%s, %02d %s %04d",
weekdayName[(t.weekDay + 6) % 7],
t.monthDay, monthName[t.month], t.year + 1900);
return buffer;
}
UString formatTime(const GregorianDateTime &t)
void formatTime(const GregorianDateTime &t, DateConversionBuffer& buffer)
{
char buffer[100];
int offset = abs(gmtoffset(t));
char timeZoneName[70];
struct tm gtm = t;
strftime(timeZoneName, sizeof(timeZoneName), "%Z", &gtm);
if (timeZoneName[0]) {
snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT%c%02d%02d (%s)",
snprintf(buffer, DateConversionBufferSize, "%02d:%02d:%02d GMT%c%02d%02d (%s)",
t.hour, t.minute, t.second,
gmtoffset(t) < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60, timeZoneName);
} else {
snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT%c%02d%02d",
snprintf(buffer, DateConversionBufferSize, "%02d:%02d:%02d GMT%c%02d%02d",
t.hour, t.minute, t.second,
gmtoffset(t) < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60);
}
return UString(buffer);
}
UString formatTimeUTC(const GregorianDateTime &t)
void formatTimeUTC(const GregorianDateTime &t, DateConversionBuffer& buffer)
{
char buffer[100];
snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT", t.hour, t.minute, t.second);
return UString(buffer);
snprintf(buffer, DateConversionBufferSize, "%02d:%02d:%02d GMT", t.hour, t.minute, t.second);
}
} // namespace JSC
......@@ -42,17 +42,21 @@
#ifndef DateConversion_h
#define DateConversion_h
#include "UString.h"
namespace JSC {
class ExecState;
class UString;
struct GregorianDateTime;
static const unsigned DateConversionBufferSize = 100;
typedef char DateConversionBuffer[DateConversionBufferSize];
double parseDate(ExecState* exec, const UString&);
UString formatDate(const GregorianDateTime&);
UString formatDateUTCVariant(const GregorianDateTime&);
UString formatTime(const GregorianDateTime&);
UString formatTimeUTC(const GregorianDateTime&);
void formatDate(const GregorianDateTime&, DateConversionBuffer&);
void formatDateUTCVariant(const GregorianDateTime&, DateConversionBuffer&);
void formatTime(const GregorianDateTime&, DateConversionBuffer&);
void formatTimeUTC(const GregorianDateTime&, DateConversionBuffer&);
} // namespace JSC
......
......@@ -423,7 +423,11 @@ JSValue JSC_HOST_CALL dateProtoFuncToString(ExecState* exec, JSObject*, JSValue
const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec);
if (!gregorianDateTime)
return jsNontrivialString(exec, "Invalid Date");
return jsNontrivialString(exec, formatDate(*gregorianDateTime) + " " + formatTime(*gregorianDateTime));
DateConversionBuffer date;
DateConversionBuffer time;
formatDate(*gregorianDateTime, date);
formatTime(*gregorianDateTime, time);
return jsNontrivialString(exec, makeString(date, " ", time));
}
JSValue JSC_HOST_CALL dateProtoFuncToUTCString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
......@@ -436,7 +440,11 @@ JSValue JSC_HOST_CALL dateProtoFuncToUTCString(ExecState* exec, JSObject*, JSVal
const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(exec);
if (!gregorianDateTime)
return jsNontrivialString(exec, "Invalid Date");
return jsNontrivialString(exec, formatDateUTCVariant(*gregorianDateTime) + " " + formatTimeUTC(*gregorianDateTime));
DateConversionBuffer date;
DateConversionBuffer time;
formatDateUTCVariant(*gregorianDateTime, date);
formatTimeUTC(*gregorianDateTime, time);
return jsNontrivialString(exec, makeString(date, " ", time));
}
JSValue JSC_HOST_CALL dateProtoFuncToISOString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
......@@ -467,7 +475,9 @@ JSValue JSC_HOST_CALL dateProtoFuncToDateString(ExecState* exec, JSObject*, JSVa
const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec);
if (!gregorianDateTime)
return jsNontrivialString(exec, "Invalid Date");
return jsNontrivialString(exec, formatDate(*gregorianDateTime));
DateConversionBuffer date;
formatDate(*gregorianDateTime, date);
return jsNontrivialString(exec, date);
}
JSValue JSC_HOST_CALL dateProtoFuncToTimeString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
......@@ -480,7 +490,9 @@ JSValue JSC_HOST_CALL dateProtoFuncToTimeString(ExecState* exec, JSObject*, JSVa
const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTime(exec);
if (!gregorianDateTime)
return jsNontrivialString(exec, "Invalid Date");
return jsNontrivialString(exec, formatTime(*gregorianDateTime));
DateConversionBuffer time;
formatTime(*gregorianDateTime, time);
return jsNontrivialString(exec, time);
}
JSValue JSC_HOST_CALL dateProtoFuncToLocaleString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
......@@ -554,7 +566,11 @@ JSValue JSC_HOST_CALL dateProtoFuncToGMTString(ExecState* exec, JSObject*, JSVal
const GregorianDateTime* gregorianDateTime = thisDateObj->gregorianDateTimeUTC(exec);
if (!gregorianDateTime)
return jsNontrivialString(exec, "Invalid Date");
return jsNontrivialString(exec, formatDateUTCVariant(*gregorianDateTime) + " " + formatTimeUTC(*gregorianDateTime));
DateConversionBuffer date;
DateConversionBuffer time;
formatDateUTCVariant(*gregorianDateTime, date);
formatTimeUTC(*gregorianDateTime, time);
return jsNontrivialString(exec, makeString(date, " ", time));
}
JSValue JSC_HOST_CALL dateProtoFuncGetMonth(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
......
......@@ -48,21 +48,19 @@ ErrorPrototype::ErrorPrototype(ExecState* exec, NonNullPassRefPtr<Structure> str
JSValue JSC_HOST_CALL errorProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
JSObject* thisObj = thisValue.toThisObject(exec);
JSValue name = thisObj->get(exec, exec->propertyNames().name);
JSValue message = thisObj->get(exec, exec->propertyNames().message);
UString s = "Error";
// Mozilla-compatible format.
JSValue v = thisObj->get(exec, exec->propertyNames().name);
if (!v.isUndefined())
s = v.toString(exec);
v = thisObj->get(exec, exec->propertyNames().message);
if (!v.isUndefined()) {
// Mozilla-compatible format.
s += ": ";
s += v.toString(exec);
if (!name.isUndefined()) {
if (!message.isUndefined())
return jsNontrivialString(exec, makeString(name.toString(exec), ": ", message.toString(exec)));
return jsNontrivialString(exec, name.toString(exec));
}
return jsNontrivialString(exec, s);
if (!message.isUndefined())
return jsNontrivialString(exec, makeString("Error: ", message.toString(exec)));
return jsNontrivialString(exec, "Error");
}
} // namespace JSC
......@@ -77,9 +77,7 @@ JSValue createUndefinedVariableError(ExecState* exec, const Identifier& ident, u
int endOffset = 0;
int divotPoint = 0;
int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset);
UString message = "Can't find variable: ";
message.append(ident.ustring());
JSObject* exception = Error::create(exec, ReferenceError, message, line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL());
JSObject* exception = Error::create(exec, ReferenceError, makeString("Can't find variable: ", ident.ustring()), line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL());
exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete);
exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete);
exception->putWithAttributes(exec, Identifier(exec, expressionEndOffsetPropertyName), jsNumber(exec, divotPoint + endOffset), ReadOnly | DontDelete);
......@@ -88,59 +86,36 @@ JSValue createUndefinedVariableError(ExecState* exec, const Identifier& ident, u
static UString createErrorMessage(ExecState* exec, CodeBlock* codeBlock, int, int expressionStart, int expressionStop, JSValue value, UString error)
{
if (!expressionStop || expressionStart > codeBlock->source()->length()) {
UString errorText = value.toString(exec);
errorText.append(" is ");
errorText.append(error);
return errorText;
}
if (!expressionStop || expressionStart > codeBlock->source()->length())
return makeString(value.toString(exec), " is ", error);
if (expressionStart < expressionStop)
return makeString("Result of expression '", codeBlock->source()->getRange(expressionStart, expressionStop), "' [", value.toString(exec), "] is ", error, ".");
UString errorText = "Result of expression ";
if (expressionStart < expressionStop) {
errorText.append('\'');
errorText.append(codeBlock->source()->getRange(expressionStart, expressionStop));
errorText.append("' [");
errorText.append(value.toString(exec));
errorText.append("] is ");
} else {
// No range information, so give a few characters of context
const UChar* data = codeBlock->source()->data();
int dataLength = codeBlock->source()->length();
int start = expressionStart;
int stop = expressionStart;
// Get up to 20 characters of context to the left and right of the divot, clamping to the line.
// then strip whitespace.
while (start > 0 && (expressionStart - start < 20) && data[start - 1] != '\n')
start--;
while (start < (expressionStart - 1) && isStrWhiteSpace(data[start]))
start++;
while (stop < dataLength && (stop - expressionStart < 20) && data[stop] != '\n')
stop++;
while (stop > expressionStart && isStrWhiteSpace(data[stop]))
stop--;
errorText.append("near '...");
errorText.append(codeBlock->source()->getRange(start, stop));
errorText.append("...' [");
errorText.append(value.toString(exec));
errorText.append("] is ");
}
errorText.append(error);
errorText.append(".");
return errorText;
// No range information, so give a few characters of context
const UChar* data = codeBlock->source()->data();
int dataLength = codeBlock->source()->length();
int start = expressionStart;
int stop = expressionStart;
// Get up to 20 characters of context to the left and right of the divot, clamping to the line.
// then strip whitespace.
while (start > 0 && (expressionStart - start < 20) && data[start - 1] != '\n')
start--;
while (start < (expressionStart - 1) && isStrWhiteSpace(data[start]))
start++;
while (stop < dataLength && (stop - expressionStart < 20) && data[stop] != '\n')
stop++;
while (stop > expressionStart && isStrWhiteSpace(data[stop]))
stop--;
return makeString("Result of expression near '...", codeBlock->source()->getRange(start, stop), "...' [", value.toString(exec), "] is ", error, ".");
}
JSObject* createInvalidParamError(ExecState* exec, const char* op, JSValue value, unsigned bytecodeOffset, CodeBlock* codeBlock)
{
UString message = "not a valid argument for '";
message.append(op);
message.append("'");
int startOffset = 0;
int endOffset = 0;
int divotPoint = 0;
int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset);
UString errorMessage = createErrorMessage(exec, codeBlock, line, divotPoint, divotPoint + endOffset, value, message);
UString errorMessage = createErrorMessage(exec, codeBlock, line, divotPoint, divotPoint + endOffset, value, makeString("not a valid argument for '", op, "'"));
JSObject* exception = Error::create(exec, TypeError, errorMessage, line, codeBlock->ownerExecutable()->sourceID(), codeBlock->ownerExecutable()->sourceURL());
exception->putWithAttributes(exec, Identifier(exec, expressionBeginOffsetPropertyName), jsNumber(exec, divotPoint - startOffset), ReadOnly | DontDelete);
exception->putWithAttributes(exec, Identifier(exec, expressionCaretOffsetPropertyName), jsNumber(exec, divotPoint), ReadOnly | DontDelete);
......
......@@ -76,7 +76,7 @@ static inline void insertSemicolonIfNeeded(UString& functionBody)
UChar ch = functionBody[i];
if (!Lexer::isWhiteSpace(ch) && !Lexer::isLineTerminator(ch)) {
if (ch != ';' && ch != '}')
functionBody = functionBody.substr(0, i + 1) + ";" + functionBody.substr(i + 1, functionBody.size() - (i + 1));
functionBody = makeString(functionBody.substr(0, i + 1), ";", functionBody.substr(i + 1, functionBody.size() - (i + 1)));
return;
}
}
......@@ -90,13 +90,13 @@ JSValue JSC_HOST_CALL functionProtoFuncToString(ExecState* exec, JSObject*, JSVa
FunctionExecutable* executable = function->jsExecutable();
UString sourceString = executable->source().toString();
insertSemicolonIfNeeded(sourceString);
return jsString(exec, "function " + function->name(exec) + "(" + executable->paramString() + ") " + sourceString);
return jsString(exec, makeString("function ", function->name(exec), "(", executable->paramString(), ") ", sourceString));
}
}
if (thisValue.inherits(&InternalFunction::info)) {
InternalFunction* function = asInternalFunction(thisValue);
return jsString(exec, "function " + function->name(exec) + "() {\n [native code]\n}");
return jsString(exec, makeString("function ", function->name(exec), "() {\n [native code]\n}"));
}
return throwError(exec, TypeError);
......
......@@ -148,7 +148,7 @@ JSValue JSC_HOST_CALL objectProtoFuncToLocaleString(ExecState* exec, JSObject*,
JSValue JSC_HOST_CALL objectProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
return jsNontrivialString(exec, "[object " + thisValue.toThisObject(exec)->className() + "]");
return jsNontrivialString(exec, makeString("[object ", thisValue.toThisObject(exec)->className(), "]"));
}
} // namespace JSC
......@@ -302,7 +302,7 @@ JSObject* constructRegExp(ExecState* exec, const ArgList& args)
RefPtr<RegExp> regExp = RegExp::create(&exec->globalData(), pattern, flags);
if (!regExp->isValid())
return throwError(exec, SyntaxError, UString("Invalid regular expression: ").append(regExp->errorMessage()));
return throwError(exec, SyntaxError, makeString("Invalid regular expression: ", regExp->errorMessage()));
return new (exec) RegExpObject(exec->lexicalGlobalObject()->regExpStructure(), regExp.release());
}
......
......@@ -142,7 +142,7 @@ bool RegExpObject::match(ExecState* exec, const ArgList& args)
UString input = args.isEmpty() ? regExpConstructor->input() : args.at(0).toString(exec);
if (input.isNull()) {
throwError(exec, GeneralError, "No input to " + toString(exec) + ".");
throwError(exec, GeneralError, makeString("No input to ", toString(exec), "."));
return false;
}
......
......@@ -91,7 +91,7 @@ JSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState* exec, JSObject*, JSValue
}
if (!regExp->isValid())
return throwError(exec, SyntaxError, UString("Invalid regular expression: ").append(regExp->errorMessage()));
return throwError(exec, SyntaxError, makeString("Invalid regular expression: ", regExp->errorMessage()));
asRegExpObject(thisValue)->setRegExp(regExp.release());
asRegExpObject(thisValue)->setLastIndex(0);
......@@ -106,15 +106,16 @@ JSValue JSC_HOST_CALL regExpProtoFuncToString(ExecState* exec, JSObject*, JSValu
return throwError(exec, TypeError);
}
UString result = "/" + asRegExpObject(thisValue)->get(exec, exec->propertyNames().source).toString(exec);
result.append('/');
char postfix[5] = { '/', 0, 0, 0, 0 };
int index = 1;
if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().global).toBoolean(exec))
result.append('g');
postfix[index++] = 'g';
if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().ignoreCase).toBoolean(exec))
result.append('i');
postfix[index++] = 'i';
if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().multiline).toBoolean(exec))
result.append('m');
return jsNontrivialString(exec, result);
postfix[index] = 'm';
return jsNontrivialString(exec, makeString("/", asRegExpObject(thisValue)->get(exec, exec->propertyNames().source).toString(exec), postfix));
}
} // namespace JSC
......@@ -775,62 +775,62 @@ JSValue JSC_HOST_CALL stringProtoFuncLocaleCompare(ExecState* exec, JSObject*, J
JSValue JSC_HOST_CALL stringProtoFuncBig(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
UString s = thisValue.toThisString(exec);
return jsNontrivialString(exec, "<big>" + s + "</big>");
return jsNontrivialString(exec, makeString("<big>", s, "</big>"));
}
JSValue JSC_HOST_CALL stringProtoFuncSmall(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
UString s = thisValue.toThisString(exec);
return jsNontrivialString(exec, "<small>" + s + "</small>");
return jsNontrivialString(exec, makeString("<small>", s, "</small>"));
}
JSValue JSC_HOST_CALL stringProtoFuncBlink(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
UString s = thisValue.toThisString(exec);
return jsNontrivialString(exec, "<blink>" + s + "</blink>");
return jsNontrivialString(exec, makeString("<blink>", s, "</blink>"));
}
JSValue JSC_HOST_CALL stringProtoFuncBold(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
UString s = thisValue.toThisString(exec);
return jsNontrivialString(exec, "<b>" + s + "</b>");
return jsNontrivialString(exec, makeString("<b>", s, "</b>"));
}
JSValue JSC_HOST_CALL stringProtoFuncFixed(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
UString s = thisValue.toThisString(exec);
return jsString(exec, "<tt>" + s + "</tt>");
return jsString(exec, makeString("<tt>", s, "</tt>"));
}
JSValue JSC_HOST_CALL stringProtoFuncItalics(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
UString s = thisValue.toThisString(exec);
return jsNontrivialString(exec, "<i>" + s + "</i>");
return jsNontrivialString(exec, makeString("<i>", s, "</i>"));
}
JSValue JSC_HOST_CALL stringProtoFuncStrike(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
UString s = thisValue.toThisString(exec);
return jsNontrivialString(exec, "<strike>" + s + "</strike>");
return jsNontrivialString(exec, makeString("<strike>", s, "</strike>"));
}
JSValue JSC_HOST_CALL stringProtoFuncSub(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
UString s = thisValue.toThisString(exec);
return jsNontrivialString(exec, "<sub>" + s + "</sub>");
return jsNontrivialString(exec, makeString("<sub>", s, "</sub>"));
}
JSValue JSC_HOST_CALL stringProtoFuncSup(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
UString s = thisValue.toThisString(exec);
return jsNontrivialString(exec, "<sup>" + s + "</sup>");
return jsNontrivialString(exec, makeString("<sup>", s, "</sup>"));
}
JSValue JSC_HOST_CALL stringProtoFuncFontcolor(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
UString s = thisValue.toThisString(exec);
JSValue a0 = args.at(0);
return jsNontrivialString(exec, "<font color=\"" + a0.toString(exec) + "\">" + s + "</font>");
return jsNontrivialString(exec, makeString("<font color=\"", a0.toString(exec), "\">", s, "</font>"));
}