summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2010-02-02 18:21:35 +0000
committerSteve Block <steveblock@google.com>2010-02-04 15:06:56 +0000
commit33fc8ca0ce504ea94c9b038e11968187fc10d13e (patch)
tree3133f325e4e2fba60b28d593fcaa6a01bf93c0cc /JavaScriptCore
parent5277f3a59aa76c1a40995a47261b9710c284f877 (diff)
downloadexternal_webkit-33fc8ca0ce504ea94c9b038e11968187fc10d13e.zip
external_webkit-33fc8ca0ce504ea94c9b038e11968187fc10d13e.tar.gz
external_webkit-33fc8ca0ce504ea94c9b038e11968187fc10d13e.tar.bz2
Merge webkit.org at r54127 : Take theirs for changes to JavaScript string addition.
The conflict is due to the fact that we cherry-picked a WebKit change http://trac.webkit.org/changeset/51978 to fix a bug. This change updates all files touched by this change to match webkit.org. See https://android-git.corp.google.com/g/#change,36411 Change-Id: Ie17c59467b74f3bf3be1149bebe086b92b30afc4
Diffstat (limited to 'JavaScriptCore')
-rw-r--r--JavaScriptCore/jit/JITStubs.cpp28
-rw-r--r--JavaScriptCore/runtime/JSString.h35
-rw-r--r--JavaScriptCore/runtime/Operations.cpp11
-rw-r--r--JavaScriptCore/runtime/Operations.h68
4 files changed, 84 insertions, 58 deletions
diff --git a/JavaScriptCore/jit/JITStubs.cpp b/JavaScriptCore/jit/JITStubs.cpp
index 9191907..bf5168b 100644
--- a/JavaScriptCore/jit/JITStubs.cpp
+++ b/JavaScriptCore/jit/JITStubs.cpp
@@ -1112,41 +1112,19 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_add)
JSValue v1 = stackFrame.args[0].jsValue();
JSValue v2 = stackFrame.args[1].jsValue();
-
- double left;
- double right = 0.0;
-
- bool rightIsNumber = v2.getNumber(right);
- if (rightIsNumber && v1.getNumber(left))
- return JSValue::encode(jsNumber(stackFrame.globalData, left + right));
-
CallFrame* callFrame = stackFrame.callFrame;
-<<<<<<< HEAD
- bool leftIsString = v1.isString();
- if (leftIsString && v2.isString()) {
- JSValue result = jsString(callFrame, asString(v1), asString(v2));
-=======
if (v1.isString()) {
JSValue result = v2.isString()
? jsString(callFrame, asString(v1), asString(v2))
: jsString(callFrame, asString(v1), v2.toPrimitiveString(callFrame));
->>>>>>> webkit.org at r54127
CHECK_FOR_EXCEPTION_AT_END();
return JSValue::encode(result);
}
- if (rightIsNumber & leftIsString) {
- RefPtr<UString::Rep> value = v2.isInt32() ?
- concatenate(asString(v1)->value(callFrame).rep(), v2.asInt32()) :
- concatenate(asString(v1)->value(callFrame).rep(), right);
-
- if (UNLIKELY(!value)) {
- throwOutOfMemoryError(callFrame);
- VM_THROW_EXCEPTION();
- }
- return JSValue::encode(jsString(stackFrame.globalData, value.release()));
- }
+ double left = 0.0, right;
+ if (v1.getNumber(left) && v2.getNumber(right))
+ return JSValue::encode(jsNumber(stackFrame.globalData, left + right));
// All other cases are pretty uncommon
JSValue result = jsAddSlowCase(callFrame, v1, v2);
diff --git a/JavaScriptCore/runtime/JSString.h b/JavaScriptCore/runtime/JSString.h
index 7288b6f..af03025 100644
--- a/JavaScriptCore/runtime/JSString.h
+++ b/JavaScriptCore/runtime/JSString.h
@@ -209,6 +209,32 @@ namespace JSC {
appendStringInConstruct(index, s2);
ASSERT(ropeLength == index);
}
+ // This constructor constructs a new string by concatenating s1 & s2.
+ // This should only be called with ropeLength <= 3.
+ JSString(JSGlobalData* globalData, unsigned ropeLength, JSString* s1, const UString& u2)
+ : JSCell(globalData->stringStructure.get())
+ , m_stringLength(s1->length() + u2.size())
+ , m_ropeLength(ropeLength)
+ {
+ ASSERT(ropeLength <= s_maxInternalRopeLength);
+ unsigned index = 0;
+ appendStringInConstruct(index, s1);
+ appendStringInConstruct(index, u2);
+ ASSERT(ropeLength == index);
+ }
+ // This constructor constructs a new string by concatenating s1 & s2.
+ // This should only be called with ropeLength <= 3.
+ JSString(JSGlobalData* globalData, unsigned ropeLength, const UString& u1, JSString* s2)
+ : JSCell(globalData->stringStructure.get())
+ , m_stringLength(u1.size() + s2->length())
+ , m_ropeLength(ropeLength)
+ {
+ ASSERT(ropeLength <= s_maxInternalRopeLength);
+ unsigned index = 0;
+ appendStringInConstruct(index, u1);
+ appendStringInConstruct(index, s2);
+ ASSERT(ropeLength == index);
+ }
// This constructor constructs a new string by concatenating v1, v2 & v3.
// This should only be called with ropeLength <= 3 ... which since every
// value must require a ropeLength of at least one implies that the length
@@ -282,13 +308,18 @@ namespace JSC {
void resolveRope(ExecState*) const;
+ void appendStringInConstruct(unsigned& index, const UString& string)
+ {
+ m_fibers[index++] = Rope::Fiber(string.rep()->ref());
+ }
+
void appendStringInConstruct(unsigned& index, JSString* jsString)
{
if (jsString->isRope()) {
for (unsigned i = 0; i < jsString->m_ropeLength; ++i)
m_fibers[index++] = jsString->m_fibers[i].ref();
} else
- m_fibers[index++] = Rope::Fiber(jsString->string().rep()->ref());
+ appendStringInConstruct(index, jsString->string());
}
void appendValueInConstructAndIncrementLength(ExecState* exec, unsigned& index, JSValue v)
@@ -335,6 +366,8 @@ namespace JSC {
unsigned ropeLength() { return m_ropeLength ? m_ropeLength : 1; }
friend JSValue jsString(ExecState* exec, JSString* s1, JSString* s2);
+ 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);
friend JSString* jsStringWithFinalizer(ExecState*, const UString&, JSStringFinalizerCallback callback, void* context);
diff --git a/JavaScriptCore/runtime/Operations.cpp b/JavaScriptCore/runtime/Operations.cpp
index 139c7b8..0e1887c 100644
--- a/JavaScriptCore/runtime/Operations.cpp
+++ b/JavaScriptCore/runtime/Operations.cpp
@@ -54,12 +54,13 @@ NEVER_INLINE JSValue jsAddSlowCase(CallFrame* callFrame, JSValue v1, JSValue v2)
JSValue p1 = v1.toPrimitive(callFrame);
JSValue p2 = v2.toPrimitive(callFrame);
- if (p1.isString() || p2.isString()) {
- RefPtr<UString::Rep> value = concatenate(p1.toString(callFrame).rep(), p2.toString(callFrame).rep());
- if (!value)
- return throwOutOfMemoryError(callFrame);
- return jsString(callFrame, value.release());
+ if (p1.isString()) {
+ return p2.isString()
+ ? jsString(callFrame, asString(p1), asString(p2))
+ : jsString(callFrame, asString(p1), p2.toString(callFrame));
}
+ if (p2.isString())
+ return jsString(callFrame, p1.toString(callFrame), asString(p2));
return jsNumber(callFrame, p1.toNumber(callFrame) + p2.toNumber(callFrame));
}
diff --git a/JavaScriptCore/runtime/Operations.h b/JavaScriptCore/runtime/Operations.h
index 5a905e3..c3aa0fa 100644
--- a/JavaScriptCore/runtime/Operations.h
+++ b/JavaScriptCore/runtime/Operations.h
@@ -37,6 +37,11 @@ namespace JSC {
ALWAYS_INLINE JSValue jsString(ExecState* exec, JSString* s1, JSString* s2)
{
+ if (!s1->length())
+ return s2;
+ if (!s2->length())
+ return s1;
+
unsigned ropeLength = s1->ropeLength() + s2->ropeLength();
JSGlobalData* globalData = &exec->globalData();
@@ -53,6 +58,42 @@ namespace JSC {
return new (globalData) JSString(globalData, rope.release());
}
+ ALWAYS_INLINE JSValue jsString(ExecState* exec, const UString& u1, JSString* s2)
+ {
+ unsigned ropeLength = 1 + s2->ropeLength();
+ JSGlobalData* globalData = &exec->globalData();
+
+ if (ropeLength <= JSString::s_maxInternalRopeLength)
+ return new (globalData) JSString(globalData, ropeLength, u1, s2);
+
+ unsigned index = 0;
+ RefPtr<JSString::Rope> rope = JSString::Rope::createOrNull(ropeLength);
+ if (UNLIKELY(!rope))
+ return throwOutOfMemoryError(exec);
+ rope->append(index, u1);
+ rope->append(index, s2);
+ ASSERT(index == ropeLength);
+ return new (globalData) JSString(globalData, rope.release());
+ }
+
+ ALWAYS_INLINE JSValue jsString(ExecState* exec, JSString* s1, const UString& u2)
+ {
+ unsigned ropeLength = s1->ropeLength() + 1;
+ JSGlobalData* globalData = &exec->globalData();
+
+ if (ropeLength <= JSString::s_maxInternalRopeLength)
+ return new (globalData) JSString(globalData, ropeLength, s1, u2);
+
+ unsigned index = 0;
+ RefPtr<JSString::Rope> rope = JSString::Rope::createOrNull(ropeLength);
+ if (UNLIKELY(!rope))
+ return throwOutOfMemoryError(exec);
+ rope->append(index, s1);
+ rope->append(index, u2);
+ ASSERT(index == ropeLength);
+ return new (globalData) JSString(globalData, rope.release());
+ }
+
ALWAYS_INLINE JSValue jsString(ExecState* exec, Register* strings, unsigned count)
{
ASSERT(count >= 3);
@@ -284,32 +325,6 @@ namespace JSC {
ALWAYS_INLINE JSValue jsAdd(CallFrame* callFrame, JSValue v1, JSValue v2)
{
-<<<<<<< HEAD
- double left;
- double right = 0.0;
-
- bool rightIsNumber = v2.getNumber(right);
- if (rightIsNumber && v1.getNumber(left))
- return jsNumber(callFrame, left + right);
-
- bool leftIsString = v1.isString();
- if (leftIsString && v2.isString()) {
- if (!asString(v1)->length())
- return asString(v2);
- if (!asString(v2)->length())
- return asString(v1);
- return jsString(callFrame, asString(v1), asString(v2));
- }
-
- if (rightIsNumber & leftIsString) {
- RefPtr<UString::Rep> value = v2.isInt32() ?
- concatenate(asString(v1)->value(callFrame).rep(), v2.asInt32()) :
- concatenate(asString(v1)->value(callFrame).rep(), right);
-
- if (!value)
- return throwOutOfMemoryError(callFrame);
- return jsString(callFrame, value.release());
-=======
double left = 0.0, right;
if (v1.getNumber(left) && v2.getNumber(right))
return jsNumber(callFrame, left + right);
@@ -318,7 +333,6 @@ namespace JSC {
return v2.isString()
? jsString(callFrame, asString(v1), asString(v2))
: jsString(callFrame, asString(v1), v2.toPrimitiveString(callFrame));
->>>>>>> webkit.org at r54127
}
// All other cases are pretty uncommon