diff options
-rw-r--r-- | src/qml/jsruntime/qv4arrayobject.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4booleanobject.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4dateobject.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4errorobject.cpp | 29 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4errorobject_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4function.cpp | 7 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4function_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4functionobject.cpp | 89 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4functionobject_p.h | 11 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4mm.cpp | 17 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4numberobject.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4object.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4objectproto.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4regexpobject.cpp | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4scopedvalue_p.h | 28 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4stringobject.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4value_def_p.h | 1 | ||||
-rw-r--r-- | src/qml/qml/qqmlxmlhttprequest.cpp | 6 | ||||
-rw-r--r-- | tools/v4/main.cpp | 6 |
20 files changed, 152 insertions, 66 deletions
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp index aa9b6af728..492dfe139b 100644 --- a/src/qml/jsruntime/qv4arrayobject.cpp +++ b/src/qml/jsruntime/qv4arrayobject.cpp @@ -49,7 +49,7 @@ using namespace QV4; DEFINE_MANAGED_VTABLE(ArrayCtor); ArrayCtor::ArrayCtor(ExecutionContext *scope) - : FunctionObject(scope, scope->engine->newIdentifier(QStringLiteral("Array"))) + : FunctionObject(scope, QStringLiteral("Array")) { vtbl = &static_vtbl; } diff --git a/src/qml/jsruntime/qv4booleanobject.cpp b/src/qml/jsruntime/qv4booleanobject.cpp index 44188e535c..be801a67c2 100644 --- a/src/qml/jsruntime/qv4booleanobject.cpp +++ b/src/qml/jsruntime/qv4booleanobject.cpp @@ -46,7 +46,7 @@ using namespace QV4; DEFINE_MANAGED_VTABLE(BooleanCtor); BooleanCtor::BooleanCtor(ExecutionContext *scope) - : FunctionObject(scope, scope->engine->newIdentifier("Boolean")) + : FunctionObject(scope, QStringLiteral("Boolean")) { vtbl = &static_vtbl; } diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp index 72dc5433e5..8bc92c6c4e 100644 --- a/src/qml/jsruntime/qv4dateobject.cpp +++ b/src/qml/jsruntime/qv4dateobject.cpp @@ -652,7 +652,7 @@ QDateTime DateObject::toQDateTime() const DEFINE_MANAGED_VTABLE(DateCtor); DateCtor::DateCtor(ExecutionContext *scope) - : FunctionObject(scope, scope->engine->newIdentifier(QStringLiteral("Date"))) + : FunctionObject(scope, QStringLiteral("Date")) { vtbl = &static_vtbl; } diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 8d85ffd4fc..821e88ee61 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -358,7 +358,7 @@ ExecutionContext *ExecutionEngine::pushGlobalContext() Returned<FunctionObject> *ExecutionEngine::newBuiltinFunction(ExecutionContext *scope, const StringRef name, ReturnedValue (*code)(SimpleCallContext *)) { - BuiltinFunction *f = new (memoryManager) BuiltinFunction(scope, name.getPointer(), code); + BuiltinFunction *f = new (memoryManager) BuiltinFunction(scope, name, code); return f->asReturned<FunctionObject>(); } diff --git a/src/qml/jsruntime/qv4errorobject.cpp b/src/qml/jsruntime/qv4errorobject.cpp index 700e17c664..7ffc4feb9e 100644 --- a/src/qml/jsruntime/qv4errorobject.cpp +++ b/src/qml/jsruntime/qv4errorobject.cpp @@ -78,6 +78,10 @@ ErrorObject::ErrorObject(InternalClass *ic) { type = Type_ErrorObject; vtbl = &static_vtbl; + + Scope scope(engine()); + ScopedValue protectThis(scope, this); + defineDefaultProperty(QStringLiteral("name"), Value::fromString(ic->engine, "Error")); } @@ -88,6 +92,10 @@ ErrorObject::ErrorObject(InternalClass *ic, const Value &message, ErrorType t) type = Type_ErrorObject; vtbl = &static_vtbl; subtype = t; + + Scope scope(engine()); + ScopedValue protectThis(scope, this); + defineAccessorProperty(QStringLiteral("stack"), ErrorObject::method_get_stack, 0); if (!message.isUndefined()) @@ -108,8 +116,11 @@ ErrorObject::ErrorObject(InternalClass *ic, const QString &message, const QStrin type = Type_ErrorObject; vtbl = &static_vtbl; subtype = t; - defineAccessorProperty(QStringLiteral("stack"), ErrorObject::method_get_stack, 0); + Scope scope(engine()); + ScopedValue protectThis(scope, this); + + defineAccessorProperty(QStringLiteral("stack"), ErrorObject::method_get_stack, 0); defineDefaultProperty(QStringLiteral("name"), Value::fromString(ic->engine, className())); stackTrace = ic->engine->stackTrace(); @@ -229,12 +240,12 @@ DEFINE_MANAGED_VTABLE(TypeErrorCtor); DEFINE_MANAGED_VTABLE(URIErrorCtor); ErrorCtor::ErrorCtor(ExecutionContext *scope) - : FunctionObject(scope, scope->engine->newIdentifier(QStringLiteral("Error"))) + : FunctionObject(scope, QStringLiteral("Error")) { vtbl = &static_vtbl; } -ErrorCtor::ErrorCtor(ExecutionContext *scope, String *name) +ErrorCtor::ErrorCtor(ExecutionContext *scope, const QString &name) : FunctionObject(scope, name) { vtbl = &static_vtbl; @@ -251,7 +262,7 @@ ReturnedValue ErrorCtor::call(Managed *that, CallData *callData) } EvalErrorCtor::EvalErrorCtor(ExecutionContext *scope) - : ErrorCtor(scope, scope->engine->newIdentifier("EvalError")) + : ErrorCtor(scope, QStringLiteral("EvalError")) { vtbl = &static_vtbl; } @@ -263,7 +274,7 @@ ReturnedValue EvalErrorCtor::construct(Managed *m, CallData *callData) } RangeErrorCtor::RangeErrorCtor(ExecutionContext *scope) - : ErrorCtor(scope, scope->engine->newIdentifier("RangeError")) + : ErrorCtor(scope, QStringLiteral("RangeError")) { vtbl = &static_vtbl; } @@ -274,7 +285,7 @@ ReturnedValue RangeErrorCtor::construct(Managed *m, CallData *callData) } ReferenceErrorCtor::ReferenceErrorCtor(ExecutionContext *scope) - : ErrorCtor(scope, scope->engine->newIdentifier("ReferenceError")) + : ErrorCtor(scope, QStringLiteral("ReferenceError")) { vtbl = &static_vtbl; } @@ -285,7 +296,7 @@ ReturnedValue ReferenceErrorCtor::construct(Managed *m, CallData *callData) } SyntaxErrorCtor::SyntaxErrorCtor(ExecutionContext *scope) - : ErrorCtor(scope, scope->engine->newIdentifier("SyntaxError")) + : ErrorCtor(scope, QStringLiteral("SyntaxError")) { vtbl = &static_vtbl; } @@ -296,7 +307,7 @@ ReturnedValue SyntaxErrorCtor::construct(Managed *m, CallData *callData) } TypeErrorCtor::TypeErrorCtor(ExecutionContext *scope) - : ErrorCtor(scope, scope->engine->newIdentifier("TypeError")) + : ErrorCtor(scope, QStringLiteral("TypeError")) { vtbl = &static_vtbl; } @@ -307,7 +318,7 @@ ReturnedValue TypeErrorCtor::construct(Managed *m, CallData *callData) } URIErrorCtor::URIErrorCtor(ExecutionContext *scope) - : ErrorCtor(scope, scope->engine->newIdentifier("URIError")) + : ErrorCtor(scope, QStringLiteral("URIError")) { vtbl = &static_vtbl; } diff --git a/src/qml/jsruntime/qv4errorobject_p.h b/src/qml/jsruntime/qv4errorobject_p.h index fb526e9b1e..1592ec791e 100644 --- a/src/qml/jsruntime/qv4errorobject_p.h +++ b/src/qml/jsruntime/qv4errorobject_p.h @@ -116,7 +116,7 @@ struct ErrorCtor: FunctionObject { Q_MANAGED ErrorCtor(ExecutionContext *scope); - ErrorCtor(ExecutionContext *scope, String *name); + ErrorCtor(ExecutionContext *scope, const QString &name); static ReturnedValue construct(Managed *, CallData *callData); static ReturnedValue call(Managed *that, CallData *callData); diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp index f69a095991..a39050aaf2 100644 --- a/src/qml/jsruntime/qv4function.cpp +++ b/src/qml/jsruntime/qv4function.cpp @@ -53,8 +53,7 @@ using namespace QV4; Function::Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit, const CompiledData::Function *function, ReturnedValue (*codePtr)(ExecutionContext *, const uchar *), quint32 _codeSize) - : name(0) - , compiledFunction(function) + : compiledFunction(function) , compilationUnit(unit) , codePtr(codePtr) , codeData(0) @@ -81,8 +80,8 @@ Function::~Function() void Function::mark() { - if (name) - name->mark(); + if (name.asManaged()) + name.asManaged()->mark(); for (int i = 0; i < formals.size(); ++i) formals.at(i)->mark(); for (int i = 0; i < locals.size(); ++i) diff --git a/src/qml/jsruntime/qv4function_p.h b/src/qml/jsruntime/qv4function_p.h index b93eded3f3..746abe910d 100644 --- a/src/qml/jsruntime/qv4function_p.h +++ b/src/qml/jsruntime/qv4function_p.h @@ -81,7 +81,7 @@ struct InternalClass; struct Lookup; struct Function { - String *name; + SafeString name; const CompiledData::Function *compiledFunction; CompiledData::CompilationUnit *compilationUnit; diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index 69c749f92f..a7332d65da 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -71,41 +71,36 @@ using namespace QV4; DEFINE_MANAGED_VTABLE(FunctionObject); -FunctionObject::FunctionObject(ExecutionContext *scope, String *name, bool createProto) +FunctionObject::FunctionObject(ExecutionContext *scope, const StringRef name, bool createProto) : Object(createProto ? scope->engine->functionWithProtoClass : scope->engine->functionClass) , scope(scope) - , name(name) , formalParameterList(0) , varList(0) , formalParameterCount(0) , varCount(0) , function(0) { - vtbl = &static_vtbl; - - type = Type_FunctionObject; - needsActivation = true; - usesArgumentsObject = false; - strictMode = false; -#ifndef QT_NO_DEBUG - assert(scope->next != (ExecutionContext *)0x1); -#endif - - if (createProto) { - Scope s(scope); - Scoped<Object> proto(s, scope->engine->newObject(scope->engine->protoClass)); - proto->memberData[Index_ProtoConstructor].value = Value::fromObject(this); - memberData[Index_Prototype].value = proto.asValue(); - } + init(name, createProto); +} - if (name) - defineReadonlyProperty(scope->engine->id_name, Value::fromString(name)); +FunctionObject::FunctionObject(ExecutionContext *scope, const QString &name, bool createProto) + : Object(createProto ? scope->engine->functionWithProtoClass : scope->engine->functionClass) + , scope(scope) + , formalParameterList(0) + , varList(0) + , formalParameterCount(0) + , varCount(0) + , function(0) +{ + Scope s(scope); + ScopedValue protectThis(s, this); + ScopedString n(s, s.engine->newString(name)); + init(n, createProto); } FunctionObject::FunctionObject(InternalClass *ic) : Object(ic) , scope(ic->engine->rootContext) - , name(name) , formalParameterList(0) , varList(0) , formalParameterCount(0) @@ -113,8 +108,12 @@ FunctionObject::FunctionObject(InternalClass *ic) , function(0) { vtbl = &static_vtbl; + name = (QV4::String *)0; type = Type_FunctionObject; + needsActivation = false; + usesArgumentsObject = false; + strictMode = false; } FunctionObject::~FunctionObject() @@ -123,6 +122,36 @@ FunctionObject::~FunctionObject() function->compilationUnit->deref(); } +void FunctionObject::init(const StringRef n, bool createProto) +{ + vtbl = &static_vtbl; + + Scope s(engine()); + ScopedValue protectThis(s, this); + + type = Type_FunctionObject; + needsActivation = true; + usesArgumentsObject = false; + strictMode = false; +#ifndef QT_NO_DEBUG + assert(scope->next != (ExecutionContext *)0x1); +#endif + + if (createProto) { + Scoped<Object> proto(s, scope->engine->newObject(scope->engine->protoClass)); + proto->memberData[Index_ProtoConstructor].value = Value::fromObject(this); + memberData[Index_Prototype].value = proto.asValue(); + } + + if (n) { + name = n; + ScopedValue v(s, n.asReturnedValue()); + defineReadonlyProperty(scope->engine->id_name, v); + } else { + name = (QV4::String *)0; + } +} + ReturnedValue FunctionObject::newInstance() { Scope scope(engine()); @@ -177,7 +206,7 @@ ReturnedValue FunctionObject::call(Managed *, CallData *) void FunctionObject::markObjects(Managed *that) { FunctionObject *o = static_cast<FunctionObject *>(that); - if (o->name) + if (o->name.managed()) o->name->mark(); // these are marked in VM::Function: // for (uint i = 0; i < formalParameterCount; ++i) @@ -202,7 +231,7 @@ FunctionObject *FunctionObject::creatScriptFunction(ExecutionContext *scope, Fun DEFINE_MANAGED_VTABLE(FunctionCtor); FunctionCtor::FunctionCtor(ExecutionContext *scope) - : FunctionObject(scope, scope->engine->newIdentifier(QStringLiteral("Function"))) + : FunctionObject(scope, QStringLiteral("Function")) { vtbl = &static_vtbl; } @@ -367,6 +396,10 @@ ScriptFunction::ScriptFunction(ExecutionContext *scope, Function *function) : FunctionObject(scope, function->name, true) { vtbl = &static_vtbl; + + Scope s(scope); + ScopedValue protectThis(s, this); + this->function = function; this->function->compilationUnit->ref(); Q_ASSERT(function); @@ -462,6 +495,10 @@ SimpleScriptFunction::SimpleScriptFunction(ExecutionContext *scope, Function *fu : FunctionObject(scope, function->name, true) { vtbl = &static_vtbl; + + Scope s(scope); + ScopedValue protectThis(s, this); + this->function = function; this->function->compilationUnit->ref(); Q_ASSERT(function); @@ -554,7 +591,7 @@ ReturnedValue SimpleScriptFunction::call(Managed *that, CallData *callData) DEFINE_MANAGED_VTABLE(BuiltinFunction); -BuiltinFunction::BuiltinFunction(ExecutionContext *scope, String *name, ReturnedValue (*code)(SimpleCallContext *)) +BuiltinFunction::BuiltinFunction(ExecutionContext *scope, const StringRef name, ReturnedValue (*code)(SimpleCallContext *)) : FunctionObject(scope, name) , code(code) { @@ -635,6 +672,10 @@ BoundFunction::BoundFunction(ExecutionContext *scope, FunctionObject *target, Va , boundArgs(boundArgs) { vtbl = &static_vtbl; + + Scope s(scope); + ScopedValue protectThis(s, this); + int len = Value::fromReturnedValue(target->get(scope->engine->id_length)).toUInt32(); len -= boundArgs.size(); if (len < 0) diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h index dfd160dbc0..d01a989ae1 100644 --- a/src/qml/jsruntime/qv4functionobject_p.h +++ b/src/qml/jsruntime/qv4functionobject_p.h @@ -106,16 +106,19 @@ struct Q_QML_EXPORT FunctionObject: Object { }; ExecutionContext *scope; - String *name; + SafeString name; String * const *formalParameterList; String * const *varList; unsigned int formalParameterCount; unsigned int varCount; Function *function; - FunctionObject(ExecutionContext *scope, String *name = 0, bool createProto = false); + FunctionObject(ExecutionContext *scope, const StringRef name, bool createProto = false); + FunctionObject(ExecutionContext *scope, const QString &name = QString(), bool createProto = false); ~FunctionObject(); + void init(const StringRef name, bool createProto); + ReturnedValue newInstance(); static ReturnedValue construct(Managed *that, CallData *); @@ -171,7 +174,7 @@ struct BuiltinFunction: FunctionObject { Q_MANAGED ReturnedValue (*code)(SimpleCallContext *); - BuiltinFunction(ExecutionContext *scope, String *name, ReturnedValue (*code)(SimpleCallContext *)); + BuiltinFunction(ExecutionContext *scope, const StringRef name, ReturnedValue (*code)(SimpleCallContext *)); static ReturnedValue construct(Managed *, CallData *); static ReturnedValue call(Managed *that, CallData *callData); @@ -185,7 +188,7 @@ struct IndexedBuiltinFunction: FunctionObject uint index; IndexedBuiltinFunction(ExecutionContext *scope, uint index, ReturnedValue (*code)(SimpleCallContext *ctx, uint index)) - : FunctionObject(scope, /*name*/0) + : FunctionObject(scope) , code(code) , index(index) { diff --git a/src/qml/jsruntime/qv4mm.cpp b/src/qml/jsruntime/qv4mm.cpp index a7e485a2a2..0233af29b9 100644 --- a/src/qml/jsruntime/qv4mm.cpp +++ b/src/qml/jsruntime/qv4mm.cpp @@ -80,6 +80,7 @@ struct MemoryManager::Data bool gcBlocked; bool scribble; bool aggressiveGC; + bool exactGC; ExecutionEngine *engine; quintptr *stackTop; @@ -113,6 +114,11 @@ struct MemoryManager::Data memset(allocCount, 0, sizeof(allocCount)); scribble = !qgetenv("MM_SCRIBBLE").isEmpty(); aggressiveGC = !qgetenv("MM_AGGRESSIVE_GC").isEmpty(); + exactGC = !qgetenv("MM_EXACT_GC").isEmpty(); + if (aggressiveGC) + qDebug() << "Using aggressive garbage collection"; + if (exactGC) + qDebug() << "Using exact garbage collection"; } ~Data() @@ -293,9 +299,11 @@ void MemoryManager::mark() # endif // CPU #endif // COMPILER - collectFromStack(); collectFromJSStack(); + if (!m_d->exactGC) + collectFromStack(); + // Preserve QObject ownership rules within JavaScript: A parent with c++ ownership // keeps all of its children alive in JavaScript. @@ -573,12 +581,7 @@ void MemoryManager::collectFromStack() const assert(i == m_d->heapChunks.count() * 2); for (; current < m_d->stackTop; ++current) { - char* genericPtr = -#if QT_POINTER_SIZE == 8 - reinterpret_cast<char *>((*current) & ~(quint64(Value::Type_Mask) << Value::Tag_Shift)); -#else - reinterpret_cast<char *>(*current); -#endif + char* genericPtr = reinterpret_cast<char *>(*current); if (genericPtr < *heapChunkBoundaries || genericPtr > *(heapChunkBoundariesEnd - 1)) continue; diff --git a/src/qml/jsruntime/qv4numberobject.cpp b/src/qml/jsruntime/qv4numberobject.cpp index 8fbc2f4d11..f946b3180a 100644 --- a/src/qml/jsruntime/qv4numberobject.cpp +++ b/src/qml/jsruntime/qv4numberobject.cpp @@ -51,7 +51,7 @@ using namespace QV4; DEFINE_MANAGED_VTABLE(NumberCtor); NumberCtor::NumberCtor(ExecutionContext *scope) - : FunctionObject(scope, scope->engine->newIdentifier(QStringLiteral("Number"))) + : FunctionObject(scope, QStringLiteral("Number")) { vtbl = &static_vtbl; } diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index e356b653e6..c2a120c7f3 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -1440,6 +1440,8 @@ ArrayObject::ArrayObject(ExecutionEngine *engine, const QStringList &list) : Object(engine->arrayClass) { init(engine); + Scope scope(engine); + ScopedValue protectThis(scope, this); // Converts a QStringList to JS. // The result is a new Array object with length equal to the length diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp index d0845735ce..0da2bf60b3 100644 --- a/src/qml/jsruntime/qv4objectproto.cpp +++ b/src/qml/jsruntime/qv4objectproto.cpp @@ -74,7 +74,7 @@ using namespace QV4; DEFINE_MANAGED_VTABLE(ObjectCtor); ObjectCtor::ObjectCtor(ExecutionContext *scope) - : FunctionObject(scope, scope->engine->newIdentifier(QStringLiteral("Object"))) + : FunctionObject(scope, QStringLiteral("Object")) { vtbl = &static_vtbl; } diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp index efe3c1fe71..697d5e35d6 100644 --- a/src/qml/jsruntime/qv4regexpobject.cpp +++ b/src/qml/jsruntime/qv4regexpobject.cpp @@ -143,6 +143,8 @@ void RegExpObject::init(ExecutionEngine *engine) type = Type_RegExpObject; Scope scope(engine); + ScopedObject protectThis(scope, this); + ScopedString lastIndex(scope, engine->newIdentifier(QStringLiteral("lastIndex"))); Property *lastIndexProperty = insertMember(lastIndex, Attr_NotEnumerable|Attr_NotConfigurable); lastIndexProperty->value = Value::fromInt32(0); @@ -228,7 +230,7 @@ uint RegExpObject::flags() const DEFINE_MANAGED_VTABLE(RegExpCtor); RegExpCtor::RegExpCtor(ExecutionContext *scope) - : FunctionObject(scope, scope->engine->newIdentifier(QStringLiteral("RegExp"))) + : FunctionObject(scope, QStringLiteral("RegExp")) { vtbl = &static_vtbl; } diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h index 5ec0497f15..09851af091 100644 --- a/src/qml/jsruntime/qv4scopedvalue_p.h +++ b/src/qml/jsruntime/qv4scopedvalue_p.h @@ -54,7 +54,7 @@ namespace QV4 { struct ScopedValue; struct Scope { - Scope(ExecutionContext *ctx) + explicit Scope(ExecutionContext *ctx) : engine(ctx->engine) #ifndef QT_NO_DEBUG , size(0) @@ -63,14 +63,17 @@ struct Scope { mark = ctx->engine->jsStackTop; } - Scope(ExecutionEngine *e) + explicit Scope(ExecutionEngine *e) : engine(e) { mark = e->jsStackTop; } ~Scope() { +#ifndef QT_NO_DEBUG Q_ASSERT(engine->jsStackTop >= mark); + memset(mark, 0, (engine->jsStackTop - mark)*sizeof(Value)); +#endif engine->jsStackTop = mark; } @@ -103,6 +106,15 @@ struct ScopedValue #endif } + ScopedValue(const Scope &scope, Managed *m) + { + ptr = scope.engine->jsStackTop++; + ptr->val = m->asReturnedValue(); +#ifndef QT_NO_DEBUG + ++scope.size; +#endif + } + ScopedValue(const Scope &scope, const ReturnedValue &v) { ptr = scope.engine->jsStackTop++; @@ -127,6 +139,11 @@ struct ScopedValue return *this; } + ScopedValue &operator=(Managed *m) { + ptr->val = m->asReturnedValue(); + return *this; + } + ScopedValue &operator=(const ReturnedValue &v) { ptr->val = v; return *this; @@ -599,6 +616,13 @@ inline Safe<T> &Safe<T>::operator=(Returned<T> *t) } template<typename T> +inline Safe<T> &Safe<T>::operator =(const Referenced<T> &v) +{ + val = v.asReturnedValue(); + return *this; +} + +template<typename T> inline Safe<T> &Safe<T>::operator=(const Safe<T> &t) { val = t.val; diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp index feee229668..5e1f9161e8 100644 --- a/src/qml/jsruntime/qv4stringobject.cpp +++ b/src/qml/jsruntime/qv4stringobject.cpp @@ -155,7 +155,7 @@ void StringObject::markObjects(Managed *that) DEFINE_MANAGED_VTABLE(StringCtor); StringCtor::StringCtor(ExecutionContext *scope) - : FunctionObject(scope, scope->engine->newIdentifier(QStringLiteral("String"))) + : FunctionObject(scope, QStringLiteral("String")) { vtbl = &static_vtbl; } diff --git a/src/qml/jsruntime/qv4value_def_p.h b/src/qml/jsruntime/qv4value_def_p.h index 3e0728bcc2..bf344a7f3d 100644 --- a/src/qml/jsruntime/qv4value_def_p.h +++ b/src/qml/jsruntime/qv4value_def_p.h @@ -366,6 +366,7 @@ struct Safe : public Value { Safe &operator =(T *t); Safe &operator =(const Scoped<T> &v); + Safe &operator =(const Referenced<T> &v); Safe &operator =(Returned<T> *t); Safe &operator =(const Safe<T> &t); diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp index 79b9344994..48072f53c8 100644 --- a/src/qml/qml/qqmlxmlhttprequest.cpp +++ b/src/qml/qml/qqmlxmlhttprequest.cpp @@ -1585,9 +1585,12 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject { Q_MANAGED QQmlXMLHttpRequestCtor(ExecutionEngine *engine) - : FunctionObject(engine->rootContext, engine->newString(QStringLiteral("XMLHttpRequest"))) + : FunctionObject(engine->rootContext, QStringLiteral("XMLHttpRequest")) { vtbl = &static_vtbl; + Scope scope(engine); + ScopedValue protectThis(scope, this); + defineReadonlyProperty(QStringLiteral("UNSENT"), Value::fromInt32(0)); defineReadonlyProperty(QStringLiteral("OPENED"), Value::fromInt32(1)); defineReadonlyProperty(QStringLiteral("HEADERS_RECEIVED"), Value::fromInt32(2)); @@ -1595,7 +1598,6 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject defineReadonlyProperty(QStringLiteral("DONE"), Value::fromInt32(4)); if (!proto) setupProto(); - Scope scope(engine); ScopedString s(scope, engine->id_prototype); defineDefaultProperty(s, Value::fromObject(proto)); } diff --git a/tools/v4/main.cpp b/tools/v4/main.cpp index ad91b88cda..8e9a880ccd 100644 --- a/tools/v4/main.cpp +++ b/tools/v4/main.cpp @@ -72,9 +72,8 @@ using namespace QV4; struct Print: FunctionObject { - Print(ExecutionContext *scope): FunctionObject(scope) { + Print(ExecutionContext *scope): FunctionObject(scope, QStringLiteral("print")) { vtbl = &static_vtbl; - name = scope->engine->newString("print"); } static ReturnedValue call(Managed *, CallData *callData) @@ -97,10 +96,9 @@ DEFINE_MANAGED_VTABLE(Print); struct GC: public FunctionObject { GC(ExecutionContext* scope) - : FunctionObject(scope) + : FunctionObject(scope, QStringLiteral("gc")) { vtbl = &static_vtbl; - name = scope->engine->newString("gc"); } static ReturnedValue call(Managed *m, CallData *) { |