aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/compiler/qv4compileddata.cpp6
-rw-r--r--src/qml/jsruntime/qv4arrayobject.cpp6
-rw-r--r--src/qml/jsruntime/qv4dateobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4engine.cpp8
-rw-r--r--src/qml/jsruntime/qv4engine_p.h5
-rw-r--r--src/qml/jsruntime/qv4errorobject.cpp2
-rw-r--r--src/qml/jsruntime/qv4function.cpp2
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp4
-rw-r--r--src/qml/jsruntime/qv4globalobject.cpp17
-rw-r--r--src/qml/jsruntime/qv4identifier.cpp2
-rw-r--r--src/qml/jsruntime/qv4identifier_p.h6
-rw-r--r--src/qml/jsruntime/qv4identifiertable.cpp65
-rw-r--r--src/qml/jsruntime/qv4identifiertable_p.h27
-rw-r--r--src/qml/jsruntime/qv4include.cpp10
-rw-r--r--src/qml/jsruntime/qv4internalclass.cpp3
-rw-r--r--src/qml/jsruntime/qv4jsonobject.cpp10
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp10
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp4
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp26
-rw-r--r--src/qml/jsruntime/qv4runtime_p.h4
-rw-r--r--src/qml/jsruntime/qv4string.cpp52
-rw-r--r--src/qml/jsruntime/qv4string_p.h56
-rw-r--r--src/qml/jsruntime/qv4stringobject.cpp14
-rw-r--r--src/qml/jsruntime/qv4value.cpp8
-rw-r--r--src/qml/jsruntime/qv4value_p.h5
-rw-r--r--src/qml/qml/qqmllocale.cpp12
-rw-r--r--src/qml/qml/v8/qv8engine.cpp2
27 files changed, 200 insertions, 168 deletions
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp
index c46392676b..34b270632d 100644
--- a/src/qml/compiler/qv4compileddata.cpp
+++ b/src/qml/compiler/qv4compileddata.cpp
@@ -68,8 +68,10 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
runtimeStrings = (QV4::String **)malloc(data->stringTableSize * sizeof(QV4::String*));
// memset the strings to 0 in case a GC run happens while we're within the loop below
memset(runtimeStrings, 0, data->stringTableSize * sizeof(QV4::String*));
- for (uint i = 0; i < data->stringTableSize; ++i)
- runtimeStrings[i] = engine->newIdentifier(data->stringAt(i));
+ for (uint i = 0; i < data->stringTableSize; ++i) {
+ // #### GC
+ runtimeStrings[i] = reinterpret_cast<QV4::String*>(engine->newIdentifier(data->stringAt(i)));
+ }
runtimeRegularExpressions = new QV4::Value[data->regexpTableSize];
// memset the regexps to 0 in case a GC run happens while we're within the loop below
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp
index 0935da3255..78cbe88ba9 100644
--- a/src/qml/jsruntime/qv4arrayobject.cpp
+++ b/src/qml/jsruntime/qv4arrayobject.cpp
@@ -205,7 +205,7 @@ ReturnedValue ArrayPrototype::method_join(CallContext *ctx)
if (scope.hasException())
return Encode::undefined();
if (!e->isNullOrUndefined())
- R += e->toString(ctx)->toQString();
+ R += e->toQString();
}
} else {
//
@@ -214,7 +214,7 @@ ReturnedValue ArrayPrototype::method_join(CallContext *ctx)
ScopedString name(scope, ctx->d()->engine->newString(QStringLiteral("0")));
ScopedValue r6(scope, self->get(name.getPointer()));
if (!r6->isNullOrUndefined())
- R = r6->toString(ctx)->toQString();
+ R = r6->toQString();
ScopedValue r12(scope);
for (quint32 k = 1; k < r2; ++k) {
@@ -226,7 +226,7 @@ ReturnedValue ArrayPrototype::method_join(CallContext *ctx)
return Encode::undefined();
if (!r12->isNullOrUndefined())
- R += r12->toString(ctx)->toQString();
+ R += r12->toQString();
}
}
diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp
index 26004b5c7e..c5d25e42ae 100644
--- a/src/qml/jsruntime/qv4dateobject.cpp
+++ b/src/qml/jsruntime/qv4dateobject.cpp
@@ -773,7 +773,7 @@ ReturnedValue DatePrototype::method_parse(CallContext *ctx)
{
if (!ctx->d()->callData->argc)
return Encode(qSNaN());
- return Encode(ParseString(ctx->d()->callData->args[0].toString(ctx)->toQString()));
+ return Encode(ParseString(ctx->d()->callData->args[0].toQString()));
}
ReturnedValue DatePrototype::method_UTC(CallContext *ctx)
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 164ad176f3..0bb05896b0 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -260,6 +260,7 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
id_byteLength = newIdentifier(QStringLiteral("byteLength"));
id_byteOffset = newIdentifier(QStringLiteral("byteOffset"));
id_buffer = newIdentifier(QStringLiteral("buffer"));
+ id_lastIndex = newIdentifier(QStringLiteral("lastIndex"));
memberDataClass = InternalClass::create(this, MemberData::staticVTable(), 0);
@@ -532,13 +533,13 @@ Heap::Object *ExecutionEngine::newObject(InternalClass *internalClass)
return object->d();
}
-Returned<String> *ExecutionEngine::newString(const QString &s)
+Heap::String *ExecutionEngine::newString(const QString &s)
{
Scope scope(this);
- return ScopedString(scope, memoryManager->alloc<String>(this, s))->asReturned<String>();
+ return ScopedString(scope, memoryManager->alloc<String>(this, s))->d();
}
-String *ExecutionEngine::newIdentifier(const QString &text)
+Heap::String *ExecutionEngine::newIdentifier(const QString &text)
{
return identifierTable->insertString(text);
}
@@ -929,6 +930,7 @@ void ExecutionEngine::markObjects()
id_byteLength->mark(this);
id_byteOffset->mark(this);
id_buffer->mark(this);
+ id_lastIndex->mark(this);
objectCtor.mark(this);
stringCtor.mark(this);
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index 5e2a6cb50b..b4219a9826 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -269,6 +269,7 @@ public:
StringValue id_byteLength;
StringValue id_byteOffset;
StringValue id_buffer;
+ StringValue id_lastIndex;
QSet<CompiledData::CompilationUnit*> compilationUnits;
@@ -308,8 +309,8 @@ public:
Heap::Object *newObject();
Heap::Object *newObject(InternalClass *internalClass);
- Returned<String> *newString(const QString &s);
- String *newIdentifier(const QString &text);
+ Heap::String *newString(const QString &s);
+ Heap::String *newIdentifier(const QString &text);
Heap::Object *newStringObject(const ValueRef value);
Heap::Object *newNumberObject(const ValueRef value);
diff --git a/src/qml/jsruntime/qv4errorobject.cpp b/src/qml/jsruntime/qv4errorobject.cpp
index b3830d82b9..7fe0574d6b 100644
--- a/src/qml/jsruntime/qv4errorobject.cpp
+++ b/src/qml/jsruntime/qv4errorobject.cpp
@@ -165,7 +165,7 @@ ReturnedValue ErrorObject::method_get_stack(CallContext *ctx)
trace += QString::number(frame.line);
}
}
- This->d()->stack = ctx->d()->engine->newString(trace)->getPointer()->d();
+ This->d()->stack = ctx->d()->engine->newString(trace);
}
return This->d()->stack->asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp
index 48be89b40a..aedbff21be 100644
--- a/src/qml/jsruntime/qv4function.cpp
+++ b/src/qml/jsruntime/qv4function.cpp
@@ -66,7 +66,7 @@ Function::Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit,
break;
}
// duplicate arguments, need some trick to store them
- arg = (s = engine->memoryManager->alloc<String>(engine, arg->d(), engine->newString(QString(0xfffe))->getPointer()->d())).getPointer();
+ arg = (s = engine->memoryManager->alloc<String>(engine, arg->d(), engine->newString(QString(0xfffe)))).getPointer();
}
}
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp
index 59c5c43ccb..79f179760d 100644
--- a/src/qml/jsruntime/qv4functionobject.cpp
+++ b/src/qml/jsruntime/qv4functionobject.cpp
@@ -213,9 +213,9 @@ ReturnedValue FunctionCtor::construct(Managed *that, CallData *callData)
for (int i = 0; i < callData->argc - 1; ++i) {
if (i)
arguments += QLatin1String(", ");
- arguments += callData->args[i].toString(ctx)->toQString();
+ arguments += callData->args[i].toQString();
}
- body = callData->args[callData->argc - 1].toString(ctx)->toQString();
+ body = callData->args[callData->argc - 1].toQString();
}
if (ctx->d()->engine->hasException)
return Encode::undefined();
diff --git a/src/qml/jsruntime/qv4globalobject.cpp b/src/qml/jsruntime/qv4globalobject.cpp
index 5baee5f4aa..f287fc7aec 100644
--- a/src/qml/jsruntime/qv4globalobject.cpp
+++ b/src/qml/jsruntime/qv4globalobject.cpp
@@ -435,13 +435,12 @@ static inline int toInt(const QChar &qc, int R)
ReturnedValue GlobalFunctions::method_parseInt(CallContext *ctx)
{
Scope scope(ctx);
- ScopedValue string(scope, ctx->argument(0));
+ ScopedValue inputString(scope, ctx->argument(0));
ScopedValue radix(scope, ctx->argument(1));
int R = radix->isUndefined() ? 0 : radix->toInt32();
// [15.1.2.2] step by step:
- String *inputString = string->toString(ctx); // 1
- QString trimmed = inputString->toQString().trimmed(); // 2
+ QString trimmed = inputString->toQString().trimmed(); // 1 + 2
if (ctx->d()->engine->hasException)
return Encode::undefined();
@@ -578,7 +577,7 @@ ReturnedValue GlobalFunctions::method_decodeURI(CallContext *context)
if (context->d()->callData->argc == 0)
return Encode::undefined();
- QString uriString = context->d()->callData->args[0].toString(context)->toQString();
+ QString uriString = context->d()->callData->args[0].toQString();
bool ok;
QString out = decode(uriString, DecodeNonReserved, &ok);
if (!ok) {
@@ -596,7 +595,7 @@ ReturnedValue GlobalFunctions::method_decodeURIComponent(CallContext *context)
if (context->d()->callData->argc == 0)
return Encode::undefined();
- QString uriString = context->d()->callData->args[0].toString(context)->toQString();
+ QString uriString = context->d()->callData->args[0].toQString();
bool ok;
QString out = decode(uriString, DecodeAll, &ok);
if (!ok) {
@@ -614,7 +613,7 @@ ReturnedValue GlobalFunctions::method_encodeURI(CallContext *context)
if (context->d()->callData->argc == 0)
return Encode::undefined();
- QString uriString = context->d()->callData->args[0].toString(context)->toQString();
+ QString uriString = context->d()->callData->args[0].toQString();
bool ok;
QString out = encode(uriString, uriUnescapedReserved, &ok);
if (!ok) {
@@ -632,7 +631,7 @@ ReturnedValue GlobalFunctions::method_encodeURIComponent(CallContext *context)
if (context->d()->callData->argc == 0)
return Encode::undefined();
- QString uriString = context->d()->callData->args[0].toString(context)->toQString();
+ QString uriString = context->d()->callData->args[0].toQString();
bool ok;
QString out = encode(uriString, uriUnescaped, &ok);
if (!ok) {
@@ -649,7 +648,7 @@ ReturnedValue GlobalFunctions::method_escape(CallContext *context)
if (!context->d()->callData->argc)
return context->d()->engine->newString(QStringLiteral("undefined"))->asReturnedValue();
- QString str = context->d()->callData->args[0].toString(context)->toQString();
+ QString str = context->d()->callData->args[0].toQString();
return context->d()->engine->newString(escape(str))->asReturnedValue();
}
@@ -658,6 +657,6 @@ ReturnedValue GlobalFunctions::method_unescape(CallContext *context)
if (!context->d()->callData->argc)
return context->d()->engine->newString(QStringLiteral("undefined"))->asReturnedValue();
- QString str = context->d()->callData->args[0].toString(context)->toQString();
+ QString str = context->d()->callData->args[0].toQString();
return context->d()->engine->newString(unescape(str))->asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4identifier.cpp b/src/qml/jsruntime/qv4identifier.cpp
index d7e0e25ddf..3432f8702d 100644
--- a/src/qml/jsruntime/qv4identifier.cpp
+++ b/src/qml/jsruntime/qv4identifier.cpp
@@ -152,7 +152,7 @@ const Identifier *IdentifierHashBase::toIdentifier(const QString &str) const
return d->identifierTable->identifier(str);
}
-const Identifier *IdentifierHashBase::toIdentifier(String *str) const
+const Identifier *IdentifierHashBase::toIdentifier(Heap::String *str) const
{
Q_ASSERT(d);
return d->identifierTable->identifier(str);
diff --git a/src/qml/jsruntime/qv4identifier_p.h b/src/qml/jsruntime/qv4identifier_p.h
index afed5c646f..a89ac29d2f 100644
--- a/src/qml/jsruntime/qv4identifier_p.h
+++ b/src/qml/jsruntime/qv4identifier_p.h
@@ -39,6 +39,10 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
+namespace Heap {
+ struct String;
+}
+
struct String;
struct IdentifierTable;
struct ExecutionEngine;
@@ -102,7 +106,7 @@ protected:
const IdentifierHashEntry *lookup(const QString &str) const;
const IdentifierHashEntry *lookup(String *str) const;
const Identifier *toIdentifier(const QString &str) const;
- const Identifier *toIdentifier(String *str) const;
+ const Identifier *toIdentifier(Heap::String *str) const;
};
diff --git a/src/qml/jsruntime/qv4identifiertable.cpp b/src/qml/jsruntime/qv4identifiertable.cpp
index 4dca1b65f1..46e309c7f3 100644
--- a/src/qml/jsruntime/qv4identifiertable.cpp
+++ b/src/qml/jsruntime/qv4identifiertable.cpp
@@ -53,41 +53,41 @@ IdentifierTable::IdentifierTable(ExecutionEngine *engine)
, numBits(8)
{
alloc = primeForNumBits(numBits);
- entries = (String **)malloc(alloc*sizeof(String *));
- memset(entries, 0, alloc*sizeof(String *));
+ entries = (Heap::String **)malloc(alloc*sizeof(Heap::String *));
+ memset(entries, 0, alloc*sizeof(Heap::String *));
}
IdentifierTable::~IdentifierTable()
{
for (int i = 0; i < alloc; ++i)
if (entries[i])
- delete entries[i]->d()->identifier;
+ delete entries[i]->identifier;
free(entries);
}
-void IdentifierTable::addEntry(String *str)
+void IdentifierTable::addEntry(Heap::String *str)
{
uint hash = str->hashValue();
- if (str->subtype() == Heap::String::StringType_ArrayIndex)
+ if (str->subtype == Heap::String::StringType_ArrayIndex)
return;
- str->d()->identifier = new Identifier;
- str->d()->identifier->string = str->toQString();
- str->d()->identifier->hashValue = hash;
+ str->identifier = new Identifier;
+ str->identifier->string = str->toQString();
+ str->identifier->hashValue = hash;
bool grow = (alloc <= size*2);
if (grow) {
++numBits;
int newAlloc = primeForNumBits(numBits);
- String **newEntries = (String **)malloc(newAlloc*sizeof(String *));
- memset(newEntries, 0, newAlloc*sizeof(String *));
+ Heap::String **newEntries = (Heap::String **)malloc(newAlloc*sizeof(Heap::String *));
+ memset(newEntries, 0, newAlloc*sizeof(Heap::String *));
for (int i = 0; i < alloc; ++i) {
- String *e = entries[i];
+ Heap::String *e = entries[i];
if (!e)
continue;
- uint idx = e->d()->stringHash % newAlloc;
+ uint idx = e->stringHash % newAlloc;
while (newEntries[idx]) {
++idx;
idx %= newAlloc;
@@ -110,49 +110,48 @@ void IdentifierTable::addEntry(String *str)
-String *IdentifierTable::insertString(const QString &s)
+Heap::String *IdentifierTable::insertString(const QString &s)
{
uint hash = String::createHashValue(s.constData(), s.length());
uint idx = hash % alloc;
- while (String *e = entries[idx]) {
- if (e->d()->stringHash == hash && e->toQString() == s)
+ while (Heap::String *e = entries[idx]) {
+ if (e->stringHash == hash && e->toQString() == s)
return e;
++idx;
idx %= alloc;
}
- Returned<String> *_s = engine->newString(s);
- String *str = _s->getPointer();
+ Heap::String *str = engine->newString(s);
addEntry(str);
return str;
}
-Identifier *IdentifierTable::identifierImpl(const String *str)
+Identifier *IdentifierTable::identifierImpl(const Heap::String *str)
{
- if (str->d()->identifier)
- return str->d()->identifier;
+ if (str->identifier)
+ return str->identifier;
uint hash = str->hashValue();
- if (str->subtype() == Heap::String::StringType_ArrayIndex)
+ if (str->subtype == Heap::String::StringType_ArrayIndex)
return 0;
uint idx = hash % alloc;
- while (String *e = entries[idx]) {
- if (e->d()->stringHash == hash && e->isEqualTo(str)) {
- str->d()->identifier = e->d()->identifier;
- return e->d()->identifier;
+ while (Heap::String *e = entries[idx]) {
+ if (e->stringHash == hash && e->isEqualTo(str)) {
+ str->identifier = e->identifier;
+ return e->identifier;
}
++idx;
idx %= alloc;
}
- addEntry(const_cast<QV4::String *>(str));
- return str->d()->identifier;
+ addEntry(const_cast<QV4::Heap::String *>(str));
+ return str->identifier;
}
Identifier *IdentifierTable::identifier(const QString &s)
{
- return insertString(s)->d()->identifier;
+ return insertString(s)->identifier;
}
Identifier *IdentifierTable::identifier(const char *s, int len)
@@ -163,16 +162,16 @@ Identifier *IdentifierTable::identifier(const char *s, int len)
QLatin1String latin(s, len);
uint idx = hash % alloc;
- while (String *e = entries[idx]) {
- if (e->d()->stringHash == hash && e->toQString() == latin)
- return e->d()->identifier;
+ while (Heap::String *e = entries[idx]) {
+ if (e->stringHash == hash && e->toQString() == latin)
+ return e->identifier;
++idx;
idx %= alloc;
}
- String *str = engine->newString(QString::fromLatin1(s, len))->getPointer();
+ Heap::String *str = engine->newString(QString::fromLatin1(s, len));
addEntry(str);
- return str->d()->identifier;
+ return str->identifier;
}
}
diff --git a/src/qml/jsruntime/qv4identifiertable_p.h b/src/qml/jsruntime/qv4identifiertable_p.h
index cc792fa3b4..fe88584c2e 100644
--- a/src/qml/jsruntime/qv4identifiertable_p.h
+++ b/src/qml/jsruntime/qv4identifiertable_p.h
@@ -49,36 +49,39 @@ struct IdentifierTable
int alloc;
int size;
int numBits;
- String **entries;
+ Heap::String **entries;
- void addEntry(String *str);
+ void addEntry(Heap::String *str);
public:
IdentifierTable(ExecutionEngine *engine);
~IdentifierTable();
- String *insertString(const QString &s);
+ Heap::String *insertString(const QString &s);
- Identifier *identifier(const String *str) {
- if (str->d()->identifier)
- return str->d()->identifier;
+ Identifier *identifier(const Heap::String *str) {
+ if (str->identifier)
+ return str->identifier;
return identifierImpl(str);
}
+ Identifier *identifier(const QV4::String *str) {
+ return identifier(str->d());
+ }
Identifier *identifier(const QString &s);
Identifier *identifier(const char *s, int len);
- Identifier *identifierImpl(const String *str);
+ Identifier *identifierImpl(const Heap::String *str);
void mark(ExecutionEngine *e) {
for (int i = 0; i < alloc; ++i) {
- String *entry = entries[i];
- if (!entry || entry->markBit())
+ Heap::String *entry = entries[i];
+ if (!entry || entry->markBit)
continue;
- entry->d()->markBit = 1;
- Q_ASSERT(entry->internalClass()->vtable->markObjects);
- entry->internalClass()->vtable->markObjects(entry->d(), e);
+ entry->markBit = 1;
+ Q_ASSERT(entry->internalClass->vtable->markObjects);
+ entry->internalClass->vtable->markObjects(entry, e);
}
}
};
diff --git a/src/qml/jsruntime/qv4include.cpp b/src/qml/jsruntime/qv4include.cpp
index 9d6a4ab10a..60ac519dfb 100644
--- a/src/qml/jsruntime/qv4include.cpp
+++ b/src/qml/jsruntime/qv4include.cpp
@@ -136,6 +136,7 @@ void QV4Include::finished()
QV4::Scope scope(v4);
QV4::ScopedObject resultObj(scope, m_resultObject.value());
+ QV4::ScopedString status(scope, v4->newString(QStringLiteral("status")));
if (m_reply->error() == QNetworkReply::NoError) {
QByteArray data = m_reply->readAll();
@@ -146,19 +147,19 @@ void QV4Include::finished()
QV4::Script script(v4, qmlglobal, code, m_url.toString());
QV4::ExecutionContext *ctx = v4->currentContext();
- QV4::ScopedString status(scope, v4->newString(QStringLiteral("status")));
script.parse();
if (!scope.engine->hasException)
script.run();
if (scope.engine->hasException) {
QV4::ScopedValue ex(scope, ctx->catchException());
resultObj->put(status.getPointer(), QV4::ScopedValue(scope, QV4::Primitive::fromInt32(Exception)));
- resultObj->put(v4->newString(QStringLiteral("exception"))->getPointer(), ex);
+ QV4::ScopedString exception(scope, v4->newString(QStringLiteral("exception")));
+ resultObj->put(exception.getPointer(), ex);
} else {
resultObj->put(status.getPointer(), QV4::ScopedValue(scope, QV4::Primitive::fromInt32(Ok)));
}
} else {
- resultObj->put(v4->newString(QStringLiteral("status"))->getPointer(), QV4::ScopedValue(scope, QV4::Primitive::fromInt32(NetworkError)));
+ resultObj->put(status.getPointer(), QV4::ScopedValue(scope, QV4::Primitive::fromInt32(NetworkError)));
}
QV4::ScopedValue cb(scope, m_callbackFunction.value());
@@ -226,7 +227,8 @@ QV4::ReturnedValue QV4Include::method_include(QV4::CallContext *ctx)
if (scope.engine->hasException) {
QV4::ScopedValue ex(scope, ctx->catchException());
result = resultValue(scope.engine, Exception);
- result->asObject()->put(scope.engine->newString(QStringLiteral("exception"))->getPointer(), ex);
+ QV4::ScopedString exception(scope, scope.engine->newString(QStringLiteral("exception")));
+ result->asObject()->put(exception.getPointer(), ex);
} else {
result = resultValue(scope.engine, Ok);
}
diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp
index 0f8eb2bfff..7247228091 100644
--- a/src/qml/jsruntime/qv4internalclass.cpp
+++ b/src/qml/jsruntime/qv4internalclass.cpp
@@ -310,7 +310,8 @@ InternalClass *InternalClass::addMemberImpl(String *string, PropertyAttributes d
// The incoming string can come from anywhere, so make sure to
// store a string in the nameMap that's guaranteed to get
// marked properly during GC.
- String *name = engine->newIdentifier(string->toQString());
+ // #### GC
+ String *name = reinterpret_cast<String*>(engine->newIdentifier(string->toQString()));
newClass->nameMap.add(newClass->size, name);
newClass->propertyData.add(newClass->size, data);
++newClass->size;
diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp
index 000ed326cd..69bd97a65d 100644
--- a/src/qml/jsruntime/qv4jsonobject.cpp
+++ b/src/qml/jsruntime/qv4jsonobject.cpp
@@ -401,7 +401,7 @@ bool JsonParser::parseValue(ValueRef val)
return false;
DEBUG << "value: string";
END;
- val = context->d()->engine->newString(value);
+ val = Value::fromHeapObject(context->d()->engine->newString(value));
return true;
}
case BeginArray: {
@@ -709,7 +709,7 @@ QString Stringify::Str(const QString &key, ValueRef v)
if (!!toJSON) {
ScopedCallData callData(scope, 1);
callData->thisObject = value;
- callData->args[0] = ctx->d()->engine->newString(key);
+ callData->args[0] = Value::fromHeapObject(ctx->d()->engine->newString(key));
value = toJSON->call(callData);
}
}
@@ -718,7 +718,7 @@ QString Stringify::Str(const QString &key, ValueRef v)
ScopedObject holder(scope, ctx->d()->engine->newObject());
holder->put(ctx, QString(), value);
ScopedCallData callData(scope, 2);
- callData->args[0] = ctx->d()->engine->newString(key);
+ callData->args[0] = Value::fromHeapObject(ctx->d()->engine->newString(key));
callData->args[1] = value;
callData->thisObject = holder;
value = replacerFunction->call(callData);
@@ -743,7 +743,7 @@ QString Stringify::Str(const QString &key, ValueRef v)
if (value->isNumber()) {
double d = value->toNumber();
- return std::isfinite(d) ? value->toString(ctx)->toQString() : QStringLiteral("null");
+ return std::isfinite(d) ? value->toQString() : QStringLiteral("null");
}
o = value.asReturnedValue();
@@ -892,7 +892,7 @@ ReturnedValue JsonObject::method_parse(CallContext *ctx)
{
Scope scope(ctx);
ScopedValue v(scope, ctx->argument(0));
- QString jtext = v->toString(ctx)->toQString();
+ QString jtext = v->toQString();
DEBUG << "parsing source = " << jtext;
JsonParser parser(ctx, jtext.constData(), jtext.length());
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index 58f98fe6ce..0ea43b9b06 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -731,7 +731,10 @@ void QObjectWrapper::advanceIterator(Managed *m, ObjectIterator *it, String *&na
const QMetaObject *mo = that->d()->object->metaObject();
const int propertyCount = mo->propertyCount();
if (it->arrayIndex < static_cast<uint>(propertyCount)) {
- name = that->engine()->newString(QString::fromUtf8(mo->property(it->arrayIndex).name()))->getPointer();
+ // #### GC
+ Scope scope(that->engine());
+ ScopedString propName(scope, that->engine()->newString(QString::fromUtf8(mo->property(it->arrayIndex).name())));
+ name = propName.getPointer();
++it->arrayIndex;
*attributes = QV4::Attr_Data;
p->value = that->get(name);
@@ -744,7 +747,10 @@ void QObjectWrapper::advanceIterator(Managed *m, ObjectIterator *it, String *&na
++it->arrayIndex;
if (method.access() == QMetaMethod::Private || index == deleteLaterIdx || index == destroyedIdx1 || index == destroyedIdx2)
continue;
- name = that->engine()->newString(QString::fromUtf8(method.name()))->getPointer();
+ // #### GC
+ Scope scope(that->engine());
+ ScopedString methodName(scope, that->engine()->newString(QString::fromUtf8(method.name())));
+ name = methodName.getPointer();
*attributes = QV4::Attr_Data;
p->value = that->get(name);
return;
diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp
index 44a8b3531e..a73c25c567 100644
--- a/src/qml/jsruntime/qv4regexpobject.cpp
+++ b/src/qml/jsruntime/qv4regexpobject.cpp
@@ -181,7 +181,7 @@ void RegExpObject::markObjects(Heap::Base *that, ExecutionEngine *e)
Property *RegExpObject::lastIndexProperty(ExecutionContext *ctx)
{
Q_UNUSED(ctx);
- Q_ASSERT(0 == internalClass()->find(ctx->d()->engine->newIdentifier(QStringLiteral("lastIndex"))));
+ Q_ASSERT(0 == internalClass()->find(ctx->d()->engine->id_lastIndex));
return propertyAt(0);
}
@@ -262,7 +262,7 @@ ReturnedValue RegExpCtor::construct(Managed *m, CallData *callData)
QString pattern;
if (!r->isUndefined())
- pattern = r->toString(ctx)->toQString();
+ pattern = r->toQString();
if (scope.hasException())
return Encode::undefined();
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index f3e85933a1..57a6524515 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -359,7 +359,7 @@ double RuntimeHelpers::stringToNumber(const QString &string)
return d;
}
-Returned<String> *RuntimeHelpers::stringFromNumber(ExecutionEngine *engine, double number)
+Heap::String *RuntimeHelpers::stringFromNumber(ExecutionEngine *engine, double number)
{
QString qstr;
RuntimeHelpers::numberToString(&qstr, number, 10);
@@ -430,23 +430,23 @@ Heap::Object *RuntimeHelpers::convertToObject(ExecutionEngine *engine, const Val
}
}
-Returned<String> *RuntimeHelpers::convertToString(ExecutionEngine *engine, const ValueRef value)
+Heap::String *RuntimeHelpers::convertToString(ExecutionEngine *engine, const ValueRef value)
{
switch (value->type()) {
case Value::Empty_Type:
Q_ASSERT(!"empty Value encountered");
case Value::Undefined_Type:
- return engine->id_undefined.ret();
+ return engine->id_undefined.getPointer()->d();
case Value::Null_Type:
- return engine->id_null.ret();
+ return engine->id_null.getPointer()->d();
case Value::Boolean_Type:
if (value->booleanValue())
- return engine->id_true.ret();
+ return engine->id_true.getPointer()->d();
else
- return engine->id_false.ret();
+ return engine->id_false.getPointer()->d();
case Value::Managed_Type:
if (value->isString())
- return value->stringValue()->asReturned<String>();
+ return value->stringValue()->d();
{
Scope scope(engine);
ScopedValue prim(scope, RuntimeHelpers::toPrimitive(value, STRING_HINT));
@@ -461,23 +461,23 @@ Returned<String> *RuntimeHelpers::convertToString(ExecutionEngine *engine, const
// This is slightly different from the method above, as
// the + operator requires a slightly different conversion
-static Returned<String> *convert_to_string_add(ExecutionEngine *engine, const ValueRef value)
+static Heap::String *convert_to_string_add(ExecutionEngine *engine, const ValueRef value)
{
switch (value->type()) {
case Value::Empty_Type:
Q_ASSERT(!"empty Value encountered");
case Value::Undefined_Type:
- return engine->id_undefined.ret();
+ return engine->id_undefined.getPointer()->d();
case Value::Null_Type:
- return engine->id_null.ret();
+ return engine->id_null.getPointer()->d();
case Value::Boolean_Type:
if (value->booleanValue())
- return engine->id_true.ret();
+ return engine->id_true.getPointer()->d();
else
- return engine->id_false.ret();
+ return engine->id_false.getPointer()->d();
case Value::Managed_Type:
if (value->isString())
- return value->stringValue()->asReturned<String>();
+ return value->stringValue()->d();
{
Scope scope(engine);
ScopedValue prim(scope, RuntimeHelpers::toPrimitive(value, PREFERREDTYPE_HINT));
diff --git a/src/qml/jsruntime/qv4runtime_p.h b/src/qml/jsruntime/qv4runtime_p.h
index 24971c695a..6be64aa8ea 100644
--- a/src/qml/jsruntime/qv4runtime_p.h
+++ b/src/qml/jsruntime/qv4runtime_p.h
@@ -221,12 +221,12 @@ struct Q_QML_PRIVATE_EXPORT RuntimeHelpers {
static ReturnedValue toPrimitive(const ValueRef value, int typeHint);
static double stringToNumber(const QString &s);
- static Returned<String> *stringFromNumber(ExecutionEngine *engine, double number);
+ static Heap::String *stringFromNumber(ExecutionEngine *engine, double number);
static double toNumber(const ValueRef value);
static void numberToString(QString *result, double num, int radix = 10);
static ReturnedValue toString(ExecutionEngine *engine, const ValueRef value);
- static Returned<String> *convertToString(ExecutionEngine *engine, const ValueRef value);
+ static Heap::String *convertToString(ExecutionEngine *engine, const ValueRef value);
static ReturnedValue toObject(ExecutionEngine *engine, const ValueRef value);
static Heap::Object *convertToObject(ExecutionEngine *engine, const ValueRef value);
diff --git a/src/qml/jsruntime/qv4string.cpp b/src/qml/jsruntime/qv4string.cpp
index 945a117364..a06a36d7fd 100644
--- a/src/qml/jsruntime/qv4string.cpp
+++ b/src/qml/jsruntime/qv4string.cpp
@@ -282,7 +282,7 @@ uint String::toUInt(bool *ok) const
*ok = true;
if (subtype() == Heap::String::StringType_Unknown)
- createHashValue();
+ d()->createHashValue();
if (subtype() >= Heap::String::StringType_UInt)
return d()->stringHash;
@@ -331,6 +331,32 @@ void Heap::String::simplifyString() const
largestSubLength = 0;
}
+void Heap::String::createHashValue() const
+{
+ if (largestSubLength)
+ simplifyString();
+ Q_ASSERT(!largestSubLength);
+ const QChar *ch = reinterpret_cast<const QChar *>(text->data());
+ const QChar *end = ch + text->size;
+
+ // array indices get their number as hash value
+ bool ok;
+ stringHash = ::toArrayIndex(ch, end, &ok);
+ if (ok) {
+ subtype = (stringHash == UINT_MAX) ? Heap::String::StringType_UInt : Heap::String::StringType_ArrayIndex;
+ return;
+ }
+
+ uint h = 0xffffffff;
+ while (ch < end) {
+ h = 31 * h + ch->unicode();
+ ++ch;
+ }
+
+ stringHash = h;
+ subtype = Heap::String::StringType_Regular;
+}
+
void Heap::String::append(const String *data, QChar *ch)
{
std::vector<const String *> worklist;
@@ -352,31 +378,7 @@ void Heap::String::append(const String *data, QChar *ch)
}
-void String::createHashValue() const
-{
- if (d()->largestSubLength)
- d()->simplifyString();
- Q_ASSERT(!d()->largestSubLength);
- const QChar *ch = reinterpret_cast<const QChar *>(d()->text->data());
- const QChar *end = ch + d()->text->size;
- // array indices get their number as hash value
- bool ok;
- d()->stringHash = ::toArrayIndex(ch, end, &ok);
- if (ok) {
- setSubtype((d()->stringHash == UINT_MAX) ? Heap::String::StringType_UInt : Heap::String::StringType_ArrayIndex);
- return;
- }
-
- uint h = 0xffffffff;
- while (ch < end) {
- h = 31 * h + ch->unicode();
- ++ch;
- }
-
- d()->stringHash = h;
- setSubtype(Heap::String::StringType_Regular);
-}
uint String::createHashValue(const QChar *ch, int length)
{
diff --git a/src/qml/jsruntime/qv4string_p.h b/src/qml/jsruntime/qv4string_p.h
index 69c9a0f892..989398883e 100644
--- a/src/qml/jsruntime/qv4string_p.h
+++ b/src/qml/jsruntime/qv4string_p.h
@@ -67,6 +67,35 @@ struct Q_QML_PRIVATE_EXPORT String : Base {
len == (uint)text->size);
return len;
}
+ void createHashValue() const;
+ inline unsigned hashValue() const {
+ if (subtype == StringType_Unknown)
+ createHashValue();
+ Q_ASSERT(!largestSubLength);
+
+ return stringHash;
+ }
+ inline QString toQString() const {
+ if (largestSubLength)
+ simplifyString();
+ QStringDataPtr ptr = { text };
+ text->ref.ref();
+ return QString(ptr);
+ }
+ inline bool isEqualTo(const String *other) const {
+ if (this == other)
+ return true;
+ if (hashValue() != other->hashValue())
+ return false;
+ Q_ASSERT(!largestSubLength);
+ if (identifier && identifier == other->identifier)
+ return true;
+ if (subtype >= Heap::String::StringType_UInt && subtype == other->subtype)
+ return true;
+
+ return toQString() == other->toQString();
+ }
+
union {
mutable QStringData *text;
mutable String *left;
@@ -96,17 +125,7 @@ struct Q_QML_PRIVATE_EXPORT String : public Managed {
bool equals(String *other) const;
inline bool isEqualTo(const String *other) const {
- if (this == other)
- return true;
- if (hashValue() != other->hashValue())
- return false;
- Q_ASSERT(!d()->largestSubLength);
- if (d()->identifier && d()->identifier == other->d()->identifier)
- return true;
- if (subtype() >= Heap::String::StringType_UInt && subtype() == other->subtype())
- return true;
-
- return toQString() == other->toQString();
+ return d()->isEqualTo(other->d());
}
inline bool compare(const String *other) {
@@ -114,23 +133,15 @@ struct Q_QML_PRIVATE_EXPORT String : public Managed {
}
inline QString toQString() const {
- if (d()->largestSubLength)
- d()->simplifyString();
- QStringDataPtr ptr = { d()->text };
- d()->text->ref.ref();
- return QString(ptr);
+ return d()->toQString();
}
inline unsigned hashValue() const {
- if (subtype() == Heap::String::StringType_Unknown)
- createHashValue();
- Q_ASSERT(!d()->largestSubLength);
-
- return d()->stringHash;
+ return d()->hashValue();
}
uint asArrayIndex() const {
if (subtype() == Heap::String::StringType_Unknown)
- createHashValue();
+ d()->createHashValue();
Q_ASSERT(!d()->largestSubLength);
if (subtype() == Heap::String::StringType_ArrayIndex)
return d()->stringHash;
@@ -146,7 +157,6 @@ struct Q_QML_PRIVATE_EXPORT String : public Managed {
void makeIdentifierImpl() const;
- void createHashValue() const;
static uint createHashValue(const QChar *ch, int length);
static uint createHashValue(const char *ch, int length);
diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp
index a21f2b284a..b9fb8812ea 100644
--- a/src/qml/jsruntime/qv4stringobject.cpp
+++ b/src/qml/jsruntime/qv4stringobject.cpp
@@ -309,7 +309,7 @@ ReturnedValue StringPrototype::method_indexOf(CallContext *context)
QString searchString;
if (context->d()->callData->argc)
- searchString = context->d()->callData->args[0].toString(context)->toQString();
+ searchString = context->d()->callData->args[0].toQString();
int pos = 0;
if (context->d()->callData->argc > 1)
@@ -480,7 +480,7 @@ ReturnedValue StringPrototype::method_replace(CallContext *ctx)
if (StringObject *thisString = ctx->d()->callData->thisObject.asStringObject())
string = thisString->d()->value.stringValue()->toQString();
else
- string = ctx->d()->callData->thisObject.toString(ctx)->toQString();
+ string = ctx->d()->callData->thisObject.toQString();
int numCaptures = 0;
int numStringMatches = 0;
@@ -522,7 +522,7 @@ ReturnedValue StringPrototype::method_replace(CallContext *ctx)
numCaptures = regExp->value()->captureCount();
} else {
numCaptures = 1;
- QString searchString = searchValue->toString(ctx)->toQString();
+ QString searchString = searchValue->toQString();
int idx = string.indexOf(searchString);
if (idx != -1) {
numStringMatches = 1;
@@ -556,16 +556,16 @@ ReturnedValue StringPrototype::method_replace(CallContext *ctx)
Q_ASSERT(matchStart >= static_cast<uint>(lastEnd));
uint matchEnd = matchOffsets[i * numCaptures * 2 + 1];
callData->args[numCaptures] = Primitive::fromUInt32(matchStart);
- callData->args[numCaptures + 1] = ctx->d()->engine->newString(string);
+ callData->args[numCaptures + 1] = Value::fromHeapObject(ctx->d()->engine->newString(string));
replacement = searchCallback->call(callData);
result += string.midRef(lastEnd, matchStart - lastEnd);
- result += replacement->toString(ctx)->toQString();
+ result += replacement->toQString();
lastEnd = matchEnd;
}
result += string.midRef(lastEnd);
} else {
- QString newString = replaceValue->toString(ctx)->toQString();
+ QString newString = replaceValue->toQString();
result.reserve(string.length() + numStringMatches*newString.size());
int lastEnd = 0;
@@ -704,7 +704,7 @@ ReturnedValue StringPrototype::method_split(CallContext *ctx)
if (array->getLength() < limit)
array->push_back((s = ctx->d()->engine->newString(text.mid(offset))));
} else {
- QString separator = separatorValue->toString(ctx)->toQString();
+ QString separator = separatorValue->toQString();
if (separator.isEmpty()) {
for (uint i = 0; i < qMin(limit, uint(text.length())); ++i)
array->push_back((s = ctx->d()->engine->newString(text.mid(i, 1))));
diff --git a/src/qml/jsruntime/qv4value.cpp b/src/qml/jsruntime/qv4value.cpp
index 410fa6482e..0600a82525 100644
--- a/src/qml/jsruntime/qv4value.cpp
+++ b/src/qml/jsruntime/qv4value.cpp
@@ -267,14 +267,14 @@ double Primitive::toInteger(double number)
}
#ifndef V4_BOOTSTRAP
-String *Value::toString(ExecutionEngine *e) const
+Heap::String *Value::toString(ExecutionEngine *e) const
{
if (isString())
- return stringValue();
- return RuntimeHelpers::convertToString(e, ValueRef::fromRawValue(this))->getPointer();
+ return stringValue()->d();
+ return RuntimeHelpers::convertToString(e, ValueRef::fromRawValue(this));
}
-String *Value::toString(ExecutionContext *ctx) const
+Heap::String *Value::toString(ExecutionContext *ctx) const
{
return toString(ctx->engine());
}
diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h
index 5126d4f0d7..a3b08ba865 100644
--- a/src/qml/jsruntime/qv4value_p.h
+++ b/src/qml/jsruntime/qv4value_p.h
@@ -343,8 +343,8 @@ struct Q_QML_PRIVATE_EXPORT Value
double toNumberImpl() const;
QString toQStringNoThrow() const;
QString toQString() const;
- String *toString(ExecutionEngine *e) const;
- String *toString(ExecutionContext *ctx) const;
+ Heap::String *toString(ExecutionEngine *e) const;
+ Heap::String *toString(ExecutionContext *ctx) const;
Heap::Object *toObject(ExecutionEngine *e) const;
Heap::Object *toObject(ExecutionContext *ctx) const;
@@ -466,6 +466,7 @@ struct TypedValue : public Value
#if QT_POINTER_SIZE == 4
tag = Managed_Type;
#endif
+ return *this;
}
TypedValue &operator =(T *t);
TypedValue &operator =(const Scoped<T> &v);
diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp
index 59671d6f6d..bed6c4c57e 100644
--- a/src/qml/qml/qqmllocale.cpp
+++ b/src/qml/qml/qqmllocale.cpp
@@ -376,9 +376,9 @@ QV4::ReturnedValue QQmlNumberExtension::method_toLocaleString(QV4::CallContext *
if (ctx->d()->callData->argc > 1) {
if (!ctx->d()->callData->args[1].isString())
V4THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
- QV4::String *fs = ctx->d()->callData->args[1].toString(ctx);
- if (fs->d()->length())
- format = fs->toQString().at(0).unicode();
+ QString fs = ctx->d()->callData->args[1].toQString();
+ if (fs.length())
+ format = fs.at(0).unicode();
}
int prec = 2;
if (ctx->d()->callData->argc > 2) {
@@ -440,12 +440,12 @@ QV4::ReturnedValue QQmlNumberExtension::method_fromLocaleString(QV4::CallContext
numberIdx = 1;
}
- QV4::String *ns = ctx->d()->callData->args[numberIdx].toString(ctx);
- if (!ns->d()->length())
+ QString ns = ctx->d()->callData->args[numberIdx].toQString();
+ if (!ns.length())
return QV4::Encode(Q_QNAN);
bool ok = false;
- double val = locale.toDouble(ns->toQString(), &ok);
+ double val = locale.toDouble(ns, &ok);
if (!ok)
V4THROW_ERROR("Locale: Number.fromLocaleString(): Invalid format")
diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp
index e3ff358f3a..63382fa0b7 100644
--- a/src/qml/qml/v8/qv8engine.cpp
+++ b/src/qml/qml/v8/qv8engine.cpp
@@ -740,7 +740,7 @@ bool QV8Engine::metaTypeFromJS(const QV4::ValueRef value, int type, void *data)
if (value->isUndefined() || value->isNull())
*reinterpret_cast<QString*>(data) = QString();
else
- *reinterpret_cast<QString*>(data) = value->toString(m_v4Engine->currentContext())->toQString();
+ *reinterpret_cast<QString*>(data) = value->toQString();
return true;
case QMetaType::Float:
*reinterpret_cast<float*>(data) = value->toNumber();