+ ALWAYS_INLINE JSValue jsString(ExecState* exec, JSString* s1, JSString* s2)
+ {
+ JSGlobalData& globalData = exec->globalData();
+
+ unsigned length1 = s1->length();
+ if (!length1)
+ return s2;
+ unsigned length2 = s2->length();
+ if (!length2)
+ return s1;
+ if ((length1 + length2) < length1)
+ return throwOutOfMemoryError(exec);
+
+ return JSRopeString::create(globalData, s1, s2);
+ }
+
+ ALWAYS_INLINE JSValue jsString(ExecState* exec, const UString& u1, const UString& u2, const UString& u3)
+ {
+ JSGlobalData* globalData = &exec->globalData();
+
+ unsigned length1 = u1.length();
+ unsigned length2 = u2.length();
+ unsigned length3 = u3.length();
+ if (!length1)
+ return jsString(exec, jsString(globalData, u2), jsString(globalData, u3));
+ if (!length2)
+ return jsString(exec, jsString(globalData, u1), jsString(globalData, u3));
+ if (!length3)
+ return jsString(exec, jsString(globalData, u1), jsString(globalData, u2));
+
+ if ((length1 + length2) < length1)
+ return throwOutOfMemoryError(exec);
+ if ((length1 + length2 + length3) < length3)
+ return throwOutOfMemoryError(exec);
+
+ return JSRopeString::create(exec->globalData(), jsString(globalData, u1), jsString(globalData, u2), jsString(globalData, u3));
+ }
+
+ ALWAYS_INLINE JSValue jsString(ExecState* exec, Register* strings, unsigned count)
+ {
+ JSGlobalData* globalData = &exec->globalData();
+ JSRopeString::RopeBuilder ropeBuilder(*globalData);
+
+ unsigned oldLength = 0;
+
+ for (unsigned i = 0; i < count; ++i) {
+ JSValue v = strings[i].jsValue();
+ ropeBuilder.append(v.toString(exec));
+
+ if (ropeBuilder.length() < oldLength) // True for overflow
+ return throwOutOfMemoryError(exec);
+ }
+
+ return ropeBuilder.release();
+ }
+
+ ALWAYS_INLINE JSValue jsStringFromArguments(ExecState* exec, JSValue thisValue)
+ {
+ JSGlobalData* globalData = &exec->globalData();
+ JSRopeString::RopeBuilder ropeBuilder(*globalData);
+ ropeBuilder.append(thisValue.toString(exec));
+
+ unsigned oldLength = 0;
+
+ for (unsigned i = 0; i < exec->argumentCount(); ++i) {
+ JSValue v = exec->argument(i);
+ ropeBuilder.append(v.toString(exec));
+
+ if (ropeBuilder.length() < oldLength) // True for overflow
+ return throwOutOfMemoryError(exec);
+ }
+
+ return ropeBuilder.release();
+ }
+