aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/compiler/qv4codegen.cpp4
-rw-r--r--src/qml/compiler/qv4compileddata.cpp14
-rw-r--r--src/qml/compiler/qv4compileddata_p.h2
-rw-r--r--src/qml/debugger/qqmlprofilerdefinitions_p.h26
-rw-r--r--src/qml/jit/qv4assembler.cpp4
-rw-r--r--src/qml/jsapi/qjsvalueiterator.cpp5
-rw-r--r--src/qml/jsruntime/jsruntime.pri10
-rw-r--r--src/qml/jsruntime/qv4argumentsobject.cpp16
-rw-r--r--src/qml/jsruntime/qv4argumentsobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4arraybuffer.cpp166
-rw-r--r--src/qml/jsruntime/qv4arraybuffer_p.h (renamed from src/qml/qml/v8/qv8debug_p.h)61
-rw-r--r--src/qml/jsruntime/qv4arraydata.cpp19
-rw-r--r--src/qml/jsruntime/qv4arraydata_p.h4
-rw-r--r--src/qml/jsruntime/qv4arrayobject.cpp25
-rw-r--r--src/qml/jsruntime/qv4booleanobject.cpp4
-rw-r--r--src/qml/jsruntime/qv4context.cpp163
-rw-r--r--src/qml/jsruntime/qv4context_p.h31
-rw-r--r--src/qml/jsruntime/qv4dataview.cpp316
-rw-r--r--src/qml/jsruntime/qv4dataview_p.h96
-rw-r--r--src/qml/jsruntime/qv4dateobject.cpp44
-rw-r--r--src/qml/jsruntime/qv4debugging.cpp1
-rw-r--r--src/qml/jsruntime/qv4engine.cpp150
-rw-r--r--src/qml/jsruntime/qv4engine_p.h52
-rw-r--r--src/qml/jsruntime/qv4errorobject.cpp12
-rw-r--r--src/qml/jsruntime/qv4errorobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4function.cpp4
-rw-r--r--src/qml/jsruntime/qv4function_p.h34
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp50
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h58
-rw-r--r--src/qml/jsruntime/qv4global_p.h5
-rw-r--r--src/qml/jsruntime/qv4globalobject.cpp8
-rw-r--r--src/qml/jsruntime/qv4identifiertable.cpp3
-rw-r--r--src/qml/jsruntime/qv4identifiertable_p.h2
-rw-r--r--src/qml/jsruntime/qv4internalclass_p.h4
-rw-r--r--src/qml/jsruntime/qv4jsonobject.cpp8
-rw-r--r--src/qml/jsruntime/qv4lookup.cpp6
-rw-r--r--src/qml/jsruntime/qv4managed.cpp2
-rw-r--r--src/qml/jsruntime/qv4managed_p.h68
-rw-r--r--src/qml/jsruntime/qv4memberdata.cpp10
-rw-r--r--src/qml/jsruntime/qv4memberdata_p.h2
-rw-r--r--src/qml/jsruntime/qv4mm.cpp15
-rw-r--r--src/qml/jsruntime/qv4mm_p.h47
-rw-r--r--src/qml/jsruntime/qv4numberobject.cpp14
-rw-r--r--src/qml/jsruntime/qv4object.cpp51
-rw-r--r--src/qml/jsruntime/qv4object_p.h63
-rw-r--r--src/qml/jsruntime/qv4objectiterator.cpp25
-rw-r--r--src/qml/jsruntime/qv4objectiterator_p.h18
-rw-r--r--src/qml/jsruntime/qv4objectproto.cpp79
-rw-r--r--src/qml/jsruntime/qv4property_p.h2
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp26
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper_p.h2
-rw-r--r--src/qml/jsruntime/qv4regexp.cpp11
-rw-r--r--src/qml/jsruntime/qv4regexp_p.h4
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp34
-rw-r--r--src/qml/jsruntime/qv4regexpobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp80
-rw-r--r--src/qml/jsruntime/qv4runtime_p.h34
-rw-r--r--src/qml/jsruntime/qv4scopedvalue_p.h25
-rw-r--r--src/qml/jsruntime/qv4script.cpp20
-rw-r--r--src/qml/jsruntime/qv4script_p.h2
-rw-r--r--src/qml/jsruntime/qv4sequenceobject.cpp9
-rw-r--r--src/qml/jsruntime/qv4sequenceobject_p.h1
-rw-r--r--src/qml/jsruntime/qv4string.cpp10
-rw-r--r--src/qml/jsruntime/qv4string_p.h16
-rw-r--r--src/qml/jsruntime/qv4stringobject.cpp20
-rw-r--r--src/qml/jsruntime/qv4stringobject_p.h2
-rw-r--r--src/qml/jsruntime/qv4typedarray.cpp572
-rw-r--r--src/qml/jsruntime/qv4typedarray_p.h133
-rw-r--r--src/qml/jsruntime/qv4value.cpp1
-rw-r--r--src/qml/jsruntime/qv4value_inl_p.h37
-rw-r--r--src/qml/jsruntime/qv4value_p.h114
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp4
-rw-r--r--src/qml/qml/qqmlboundsignal.cpp6
-rw-r--r--src/qml/qml/qqmlboundsignal_p.h2
-rw-r--r--src/qml/qml/qqmlcomponent.cpp23
-rw-r--r--src/qml/qml/qqmlcontextwrapper.cpp18
-rw-r--r--src/qml/qml/qqmlcontextwrapper_p.h4
-rw-r--r--src/qml/qml/qqmllistwrapper.cpp1
-rw-r--r--src/qml/qml/qqmllocale_p.h2
-rw-r--r--src/qml/qml/qqmltypewrapper.cpp2
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper.cpp10
-rw-r--r--src/qml/qml/qqmlxmlhttprequest.cpp61
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp28
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions_p.h2
-rw-r--r--src/qml/qml/v8/qv4domerrors_p.h2
-rw-r--r--src/qml/qml/v8/qv8engine.cpp17
-rw-r--r--src/qml/qml/v8/qv8engine_p.h4
-rw-r--r--src/qml/qml/v8/v8.pri1
-rw-r--r--src/qml/types/qqmldelegatemodel.cpp25
-rw-r--r--src/qml/util/qqmladaptormodel.cpp16
90 files changed, 2229 insertions, 963 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index a7b5326861..c66202262b 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -2861,7 +2861,7 @@ void RuntimeCodegen::throwSyntaxError(const AST::SourceLocation &loc, const QStr
if (hasError)
return;
hasError = true;
- context->throwSyntaxError(detail, _module->fileName, loc.startLine, loc.startColumn);
+ context->engine()->throwSyntaxError(detail, _module->fileName, loc.startLine, loc.startColumn);
}
void RuntimeCodegen::throwReferenceError(const AST::SourceLocation &loc, const QString &detail)
@@ -2869,7 +2869,7 @@ void RuntimeCodegen::throwReferenceError(const AST::SourceLocation &loc, const Q
if (hasError)
return;
hasError = true;
- context->throwReferenceError(detail, _module->fileName, loc.startLine, loc.startColumn);
+ context->engine()->throwReferenceError(detail, _module->fileName, loc.startLine, loc.startColumn);
}
#endif // V4_BOOTSTRAP
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp
index d242fb7b3a..fbef8b8566 100644
--- a/src/qml/compiler/qv4compileddata.cpp
+++ b/src/qml/compiler/qv4compileddata.cpp
@@ -65,9 +65,9 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
Q_ASSERT(!runtimeStrings);
Q_ASSERT(data);
- runtimeStrings = (QV4::StringValue *)malloc(data->stringTableSize * sizeof(QV4::StringValue));
+ 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::StringValue));
+ memset(runtimeStrings, 0, data->stringTableSize * sizeof(QV4::String*));
for (uint i = 0; i < data->stringTableSize; ++i)
runtimeStrings[i] = engine->newIdentifier(data->stringAt(i));
@@ -109,7 +109,7 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
l->classList[j] = 0;
l->level = -1;
l->index = UINT_MAX;
- l->name = runtimeStrings[compiledLookups[i].nameIndex].asString();
+ l->name = runtimeStrings[compiledLookups[i].nameIndex];
if (type == CompiledData::Lookup::Type_IndexedGetter || type == CompiledData::Lookup::Type_IndexedSetter)
l->engine = engine;
}
@@ -123,7 +123,7 @@ QV4::Function *CompilationUnit::linkToEngine(ExecutionEngine *engine)
const CompiledData::JSClassMember *member = data->jsClassAt(i, &memberCount);
QV4::InternalClass *klass = engine->objectClass;
for (int j = 0; j < memberCount; ++j, ++member)
- klass = klass->addMember(runtimeStrings[member->nameOffset].asString(), member->isAccessor ? QV4::Attr_Accessor : QV4::Attr_Data);
+ klass = klass->addMember(runtimeStrings[member->nameOffset], member->isAccessor ? QV4::Attr_Accessor : QV4::Attr_Data);
runtimeClasses[i] = klass;
}
@@ -166,14 +166,16 @@ void CompilationUnit::unlink()
void CompilationUnit::markObjects(QV4::ExecutionEngine *e)
{
for (uint i = 0; i < data->stringTableSize; ++i)
- runtimeStrings[i].mark(e);
+ if (runtimeStrings[i])
+ runtimeStrings[i]->mark(e);
if (runtimeRegularExpressions) {
for (uint i = 0; i < data->regexpTableSize; ++i)
runtimeRegularExpressions[i].mark(e);
}
if (runtimeLookups) {
for (uint i = 0; i < data->lookupTableSize; ++i)
- runtimeLookups[i].name->mark(e);
+ if (runtimeLookups[i].name)
+ runtimeLookups[i].name->mark(e);
}
}
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h
index 6791970461..6ab7191358 100644
--- a/src/qml/compiler/qv4compileddata_p.h
+++ b/src/qml/compiler/qv4compileddata_p.h
@@ -588,7 +588,7 @@ struct Q_QML_PRIVATE_EXPORT CompilationUnit : public QQmlRefCount
ExecutionEngine *engine;
QString fileName() const { return data->stringAt(data->sourceFileIndex); }
- QV4::StringValue *runtimeStrings; // Array
+ QV4::String **runtimeStrings; // Array
QV4::Lookup *runtimeLookups;
QV4::Value *runtimeRegularExpressions;
QV4::InternalClass **runtimeClasses;
diff --git a/src/qml/debugger/qqmlprofilerdefinitions_p.h b/src/qml/debugger/qqmlprofilerdefinitions_p.h
index e8ee98433d..713134f394 100644
--- a/src/qml/debugger/qqmlprofilerdefinitions_p.h
+++ b/src/qml/debugger/qqmlprofilerdefinitions_p.h
@@ -107,18 +107,20 @@ struct QQmlProfilerDefinitions {
};
enum SceneGraphFrameType {
- SceneGraphRendererFrame,
- SceneGraphAdaptationLayerFrame,
- SceneGraphContextFrame,
- SceneGraphRenderLoopFrame,
- SceneGraphTexturePrepare,
- SceneGraphTextureDeletion,
- SceneGraphPolishAndSync,
- SceneGraphWindowsRenderShow,
- SceneGraphWindowsAnimations,
- SceneGraphPolishFrame,
-
- MaximumSceneGraphFrameType
+ SceneGraphRendererFrame, // Render Thread
+ SceneGraphAdaptationLayerFrame, // Render Thread
+ SceneGraphContextFrame, // Render Thread
+ SceneGraphRenderLoopFrame, // Render Thread
+ SceneGraphTexturePrepare, // Render Thread
+ SceneGraphTextureDeletion, // Render Thread
+ SceneGraphPolishAndSync, // GUI Thread
+ SceneGraphWindowsRenderShow, // Unused
+ SceneGraphWindowsAnimations, // GUI Thread
+ SceneGraphPolishFrame, // GUI Thread
+
+ MaximumSceneGraphFrameType,
+ NumRenderThreadFrameTypes = SceneGraphPolishAndSync,
+ NumGUIThreadFrameTypes = MaximumSceneGraphFrameType - NumRenderThreadFrameTypes
};
typedef QV4::Profiling::MemoryType MemoryType;
diff --git a/src/qml/jit/qv4assembler.cpp b/src/qml/jit/qv4assembler.cpp
index ed342740ac..300f4b0fb2 100644
--- a/src/qml/jit/qv4assembler.cpp
+++ b/src/qml/jit/qv4assembler.cpp
@@ -214,7 +214,7 @@ Assembler::Pointer Assembler::loadStringAddress(RegisterID reg, const QString &s
loadPtr(Address(Assembler::ContextRegister, qOffsetOf(QV4::ExecutionContext::Data, compilationUnit)), Assembler::ScratchRegister);
loadPtr(Address(Assembler::ScratchRegister, qOffsetOf(QV4::CompiledData::CompilationUnit, runtimeStrings)), reg);
const int id = _isel->registerString(string);
- return Pointer(reg, id * sizeof(QV4::StringValue));
+ return Pointer(reg, id * sizeof(QV4::String*));
}
void Assembler::loadStringRef(RegisterID reg, const QString &string)
@@ -222,7 +222,7 @@ void Assembler::loadStringRef(RegisterID reg, const QString &string)
loadPtr(Address(Assembler::ContextRegister, qOffsetOf(QV4::ExecutionContext::Data, compilationUnit)), reg);
loadPtr(Address(reg, qOffsetOf(QV4::CompiledData::CompilationUnit, runtimeStrings)), reg);
const int id = _isel->registerString(string);
- loadPtr(Address(reg, id * sizeof(QV4::StringValue)), reg);
+ loadPtr(Address(reg, id * sizeof(QV4::String*)), reg);
}
void Assembler::storeValue(QV4::Primitive value, IR::Expr *destination)
diff --git a/src/qml/jsapi/qjsvalueiterator.cpp b/src/qml/jsapi/qjsvalueiterator.cpp
index f7976e7cfc..cc6953cbf7 100644
--- a/src/qml/jsapi/qjsvalueiterator.cpp
+++ b/src/qml/jsapi/qjsvalueiterator.cpp
@@ -36,6 +36,7 @@
#include "qjsvalue_p.h"
#include "private/qv4string_p.h"
#include "private/qv4object_p.h"
+#include "private/qv4context_p.h"
QT_BEGIN_NAMESPACE
@@ -51,7 +52,7 @@ QJSValueIteratorPrivate::QJSValueIteratorPrivate(const QJSValue &v)
QV4::Scope scope(e);
QV4::ScopedObject o(scope, jsp->value);
- iterator = e->newForEachIteratorObject(e->currentContext(), o)->asReturnedValue();
+ iterator = e->newForEachIteratorObject(o)->asReturnedValue();
currentName = (QV4::String *)0;
nextName = (QV4::String *)0;
@@ -223,7 +224,7 @@ QJSValueIterator& QJSValueIterator::operator=(QJSValue& object)
QJSValuePrivate *jsp = QJSValuePrivate::get(object);
QV4::Scope scope(v4);
QV4::ScopedObject o(scope, jsp->value);
- d_ptr->iterator = v4->newForEachIteratorObject(v4->currentContext(), o)->asReturnedValue();
+ d_ptr->iterator = v4->newForEachIteratorObject(o)->asReturnedValue();
QV4::Scoped<QV4::ForEachIteratorObject> it(scope, d_ptr->iterator.value());
it->d()->it.flags = QV4::ObjectIterator::NoFlags;
QV4::String *nm = 0;
diff --git a/src/qml/jsruntime/jsruntime.pri b/src/qml/jsruntime/jsruntime.pri
index c27aaa90d8..ef44ca6f4d 100644
--- a/src/qml/jsruntime/jsruntime.pri
+++ b/src/qml/jsruntime/jsruntime.pri
@@ -42,7 +42,10 @@ SOURCES += \
$$PWD/qv4qobjectwrapper.cpp \
$$PWD/qv4qmlextensions.cpp \
$$PWD/qv4vme_moth.cpp \
- $$PWD/qv4profiling.cpp
+ $$PWD/qv4profiling.cpp \
+ $$PWD/qv4arraybuffer.cpp \
+ $$PWD/qv4typedarray.cpp \
+ $$PWD/qv4dataview.cpp
HEADERS += \
$$PWD/qv4global_p.h \
@@ -89,7 +92,10 @@ HEADERS += \
$$PWD/qv4qobjectwrapper_p.h \
$$PWD/qv4qmlextensions_p.h \
$$PWD/qv4vme_moth_p.h \
- $$PWD/qv4profiling_p.h
+ $$PWD/qv4profiling_p.h \
+ $$PWD/qv4arraybuffer_p.h \
+ $$PWD/qv4typedarray_p.h \
+ $$PWD/qv4dataview_p.h
}
diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp
index 4af8927a2e..e8cb788b74 100644
--- a/src/qml/jsruntime/qv4argumentsobject.cpp
+++ b/src/qml/jsruntime/qv4argumentsobject.cpp
@@ -134,7 +134,7 @@ bool ArgumentsObject::defineOwnProperty(ExecutionContext *ctx, uint index, const
}
if (ctx->d()->strictMode && !result)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
return result;
}
@@ -200,7 +200,7 @@ ReturnedValue ArgumentsGetterFunction::call(Managed *getter, CallData *callData)
Scoped<ArgumentsGetterFunction> g(scope, static_cast<ArgumentsGetterFunction *>(getter));
Scoped<ArgumentsObject> o(scope, callData->thisObject.as<ArgumentsObject>());
if (!o)
- return v4->currentContext()->throwTypeError();
+ return v4->throwTypeError();
Q_ASSERT(g->index() < static_cast<unsigned>(o->context()->d()->callData->argc));
return o->context()->argument(g->index());
@@ -215,19 +215,19 @@ ReturnedValue ArgumentsSetterFunction::call(Managed *setter, CallData *callData)
Scoped<ArgumentsSetterFunction> s(scope, static_cast<ArgumentsSetterFunction *>(setter));
Scoped<ArgumentsObject> o(scope, callData->thisObject.as<ArgumentsObject>());
if (!o)
- return v4->currentContext()->throwTypeError();
+ return v4->throwTypeError();
Q_ASSERT(s->index() < static_cast<unsigned>(o->context()->d()->callData->argc));
o->context()->d()->callData->args[s->index()] = callData->argc ? callData->args[0].asReturnedValue() : Encode::undefined();
return Encode::undefined();
}
-void ArgumentsObject::markObjects(Managed *that, ExecutionEngine *e)
+void ArgumentsObject::markObjects(HeapObject *that, ExecutionEngine *e)
{
- ArgumentsObject *o = static_cast<ArgumentsObject *>(that);
- if (o->context())
- o->context()->mark(e);
- o->mappedArguments().mark(e);
+ ArgumentsObject::Data *o = static_cast<ArgumentsObject::Data *>(that);
+ if (o->context)
+ o->context->mark(e);
+ o->mappedArguments.mark(e);
Object::markObjects(that, e);
}
diff --git a/src/qml/jsruntime/qv4argumentsobject_p.h b/src/qml/jsruntime/qv4argumentsobject_p.h
index 786cb36d0a..73c6bb26f3 100644
--- a/src/qml/jsruntime/qv4argumentsobject_p.h
+++ b/src/qml/jsruntime/qv4argumentsobject_p.h
@@ -106,7 +106,7 @@ struct ArgumentsObject: Object {
static void putIndexed(Managed *m, uint index, const ValueRef value);
static bool deleteIndexedProperty(Managed *m, uint index);
static PropertyAttributes queryIndexed(const Managed *m, uint index);
- static void markObjects(Managed *that, ExecutionEngine *e);
+ static void markObjects(HeapObject *that, ExecutionEngine *e);
void fullyCreate();
};
diff --git a/src/qml/jsruntime/qv4arraybuffer.cpp b/src/qml/jsruntime/qv4arraybuffer.cpp
new file mode 100644
index 0000000000..82ab2a2a87
--- /dev/null
+++ b/src/qml/jsruntime/qv4arraybuffer.cpp
@@ -0,0 +1,166 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "qv4arraybuffer_p.h"
+#include "qv4typedarray_p.h"
+#include "qv4dataview_p.h"
+
+using namespace QV4;
+
+DEFINE_OBJECT_VTABLE(ArrayBufferCtor);
+DEFINE_OBJECT_VTABLE(ArrayBuffer);
+
+ArrayBufferCtor::Data::Data(ExecutionContext *scope)
+ : FunctionObject::Data(scope, QStringLiteral("ArrayBuffer"))
+{
+ setVTable(staticVTable());
+}
+
+ReturnedValue ArrayBufferCtor::construct(Managed *m, CallData *callData)
+{
+ ExecutionEngine *v4 = m->engine();
+
+ Scope scope(v4);
+ ScopedValue l(scope, callData->argument(0));
+ double dl = l->toInteger();
+ if (v4->hasException)
+ return Encode::undefined();
+ uint len = (uint)qBound(0., dl, (double)UINT_MAX);
+ if (len != dl)
+ return v4->throwRangeError(QLatin1String("ArrayBuffer constructor: invalid length"));
+
+ Scoped<ArrayBuffer> a(scope, v4->memoryManager->alloc<ArrayBuffer>(v4, len));
+ if (scope.engine->hasException)
+ return Encode::undefined();
+ return a.asReturnedValue();
+}
+
+
+ReturnedValue ArrayBufferCtor::call(Managed *that, CallData *callData)
+{
+ return construct(that, callData);
+}
+
+ReturnedValue ArrayBufferCtor::method_isView(CallContext *ctx)
+{
+ QV4::Scope scope(ctx);
+ QV4::Scoped<TypedArray> a(scope, ctx->argument(0));
+ if (!!a)
+ return Encode(true);
+ QV4::Scoped<DataView> v(scope, ctx->argument(0));
+ if (!!v)
+ return Encode(true);
+ return Encode(true);
+}
+
+
+ArrayBuffer::Data::Data(ExecutionEngine *e, int length)
+ : Object::Data(e->arrayBufferClass)
+{
+ data = QTypedArrayData<char>::allocate(length + 1);
+ if (!data) {
+ data = 0;
+ e->throwRangeError(QStringLiteral("ArrayBuffer: out of memory"));
+ return;
+ }
+ data->size = length;
+ memset(data->data(), 0, length + 1);
+}
+
+QByteArray ArrayBuffer::asByteArray() const
+{
+ QByteArrayDataPtr ba = { d()->data };
+ ba.ptr->ref.ref();
+ return QByteArray(ba);
+}
+
+void ArrayBuffer::destroy(Managed *m)
+{
+ ArrayBuffer *b = static_cast<ArrayBuffer *>(m);
+ if (!b->d()->data->ref.deref())
+ QTypedArrayData<char>::deallocate(b->d()->data);
+}
+
+
+void ArrayBufferPrototype::init(ExecutionEngine *engine, Object *ctor)
+{
+ Scope scope(engine);
+ ScopedObject o(scope);
+ ctor->defineReadonlyProperty(engine->id_length, Primitive::fromInt32(1));
+ ctor->defineReadonlyProperty(engine->id_prototype, (o = this));
+ ctor->defineDefaultProperty(QStringLiteral("isView"), ArrayBufferCtor::method_isView, 1);
+ defineDefaultProperty(engine->id_constructor, (o = ctor));
+ defineAccessorProperty(QStringLiteral("byteLength"), method_get_byteLength, 0);
+ defineDefaultProperty(QStringLiteral("slice"), method_slice, 2);
+}
+
+ReturnedValue ArrayBufferPrototype::method_get_byteLength(CallContext *ctx)
+{
+ Scope scope(ctx);
+ Scoped<ArrayBuffer> v(scope, ctx->d()->callData->thisObject);
+ if (!v)
+ return scope.engine->throwTypeError();
+
+ return Encode(v->d()->data->size);
+}
+
+ReturnedValue ArrayBufferPrototype::method_slice(CallContext *ctx)
+{
+ Scope scope(ctx);
+ Scoped<ArrayBuffer> a(scope, ctx->d()->callData->thisObject);
+ if (!a)
+ return scope.engine->throwTypeError();
+
+ double start = ctx->d()->callData->argc > 0 ? ctx->d()->callData->args[0].toInteger() : 0;
+ double end = (ctx->d()->callData->argc < 2 || ctx->d()->callData->args[1].isUndefined()) ?
+ a->d()->data->size : ctx->d()->callData->args[1].toInteger();
+ if (scope.engine->hasException)
+ return Encode::undefined();
+
+ double first = (start < 0) ? qMax(a->d()->data->size + start, 0.) : qMin(start, (double)a->d()->data->size);
+ double final = (end < 0) ? qMax(a->d()->data->size + end, 0.) : qMin(end, (double)a->d()->data->size);
+
+ Scoped<FunctionObject> constructor(scope, a->get(scope.engine->id_constructor));
+ if (!constructor)
+ return scope.engine->throwTypeError();
+
+ ScopedCallData callData(scope, 1);
+ double newLen = qMax(final - first, 0.);
+ callData->args[0] = QV4::Encode(newLen);
+ QV4::Scoped<ArrayBuffer> newBuffer(scope, constructor->construct(callData));
+ if (!newBuffer || newBuffer->d()->data->size < (int)newLen)
+ return scope.engine->throwTypeError();
+
+ memcpy(newBuffer->d()->data->data(), a->d()->data->data() + (uint)first, newLen);
+
+ return newBuffer.asReturnedValue();
+}
diff --git a/src/qml/qml/v8/qv8debug_p.h b/src/qml/jsruntime/qv4arraybuffer_p.h
index 75342aa070..57ee34e570 100644
--- a/src/qml/qml/v8/qv8debug_p.h
+++ b/src/qml/jsruntime/qv4arraybuffer_p.h
@@ -30,5 +30,64 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+#ifndef QV4ARRAYBUFFER_H
+#define QV4ARRAYBUFFER_H
-//#include <private/v8-debug.h>
+#include "qv4object_p.h"
+#include "qv4functionobject_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace QV4 {
+
+struct ArrayBufferCtor: FunctionObject
+{
+ struct Data : FunctionObject::Data {
+ Data(ExecutionContext *scope);
+ };
+
+ V4_OBJECT(FunctionObject)
+
+ static ReturnedValue construct(Managed *m, CallData *callData);
+ static ReturnedValue call(Managed *that, CallData *callData);
+
+ static ReturnedValue method_isView(CallContext *ctx);
+
+};
+
+struct ArrayBuffer : Object
+{
+ struct Data : Object::Data {
+ Data(ExecutionEngine *e, int length);
+ QTypedArrayData<char> *data;
+ };
+ V4_OBJECT(Object)
+
+ QByteArray asByteArray() const;
+ uint byteLength() const { return d()->data->size; }
+ char *data() {
+ // ### detach if refcount > 1
+ return d()->data->data();
+ }
+ const char *constData() {
+ // ### detach if refcount > 1
+ return d()->data->data();
+ }
+
+ static void destroy(Managed *m);
+};
+
+struct ArrayBufferPrototype: Object
+{
+ void init(ExecutionEngine *engine, Object *ctor);
+
+ static ReturnedValue method_get_byteLength(CallContext *ctx);
+ static ReturnedValue method_slice(CallContext *ctx);
+};
+
+
+} // namespace QV4
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp
index 35bd6e5501..5aaed1a98d 100644
--- a/src/qml/jsruntime/qv4arraydata.cpp
+++ b/src/qml/jsruntime/qv4arraydata.cpp
@@ -34,6 +34,7 @@
#include "qv4object_p.h"
#include "qv4functionobject_p.h"
#include "qv4mm_p.h"
+#include "qv4runtime_p.h"
using namespace QV4;
@@ -212,12 +213,12 @@ void ArrayData::ensureAttributes(Object *o)
}
-void SimpleArrayData::markObjects(Managed *d, ExecutionEngine *e)
+void SimpleArrayData::markObjects(HeapObject *d, ExecutionEngine *e)
{
- SimpleArrayData *dd = static_cast<SimpleArrayData *>(d);
- uint l = dd->len();
+ SimpleArrayData::Data *dd = static_cast<SimpleArrayData::Data *>(d);
+ uint l = dd->len;
for (uint i = 0; i < l; ++i)
- dd->data(i).mark(e);
+ dd->arrayData[i].mark(e);
}
ReturnedValue SimpleArrayData::get(const ArrayData *d, uint index)
@@ -362,12 +363,12 @@ void SparseArrayData::destroy(Managed *d)
delete dd->sparse();
}
-void SparseArrayData::markObjects(Managed *d, ExecutionEngine *e)
+void SparseArrayData::markObjects(HeapObject *d, ExecutionEngine *e)
{
- SparseArrayData *dd = static_cast<SparseArrayData *>(d);
- uint l = dd->alloc();
+ SparseArrayData::Data *dd = static_cast<SparseArrayData::Data *>(d);
+ uint l = dd->alloc;
for (uint i = 0; i < l; ++i)
- dd->arrayData()[i].mark(e);
+ dd->arrayData[i].mark(e);
}
ArrayData *SparseArrayData::reallocate(Object *o, uint n, bool enforceAttributes)
@@ -746,7 +747,7 @@ void ArrayData::sort(ExecutionContext *context, Object *thisObject, const ValueR
return;
if (!(comparefn->isUndefined() || comparefn->asObject())) {
- context->throwTypeError();
+ context->engine()->throwTypeError();
return;
}
diff --git a/src/qml/jsruntime/qv4arraydata_p.h b/src/qml/jsruntime/qv4arraydata_p.h
index b69d200665..5286be875b 100644
--- a/src/qml/jsruntime/qv4arraydata_p.h
+++ b/src/qml/jsruntime/qv4arraydata_p.h
@@ -172,7 +172,7 @@ struct Q_QML_EXPORT SimpleArrayData : public ArrayData
static ArrayData *reallocate(Object *o, uint n, bool enforceAttributes);
- static void markObjects(Managed *d, ExecutionEngine *e);
+ static void markObjects(HeapObject *d, ExecutionEngine *e);
static ReturnedValue get(const ArrayData *d, uint index);
static bool put(Object *o, uint index, ValueRef value);
@@ -218,7 +218,7 @@ struct Q_QML_EXPORT SparseArrayData : public ArrayData
}
static void destroy(Managed *d);
- static void markObjects(Managed *d, ExecutionEngine *e);
+ static void markObjects(HeapObject *d, ExecutionEngine *e);
static ArrayData *reallocate(Object *o, uint n, bool enforceAttributes);
static ReturnedValue get(const ArrayData *d, uint index);
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp
index 011279ae07..bbc0867c22 100644
--- a/src/qml/jsruntime/qv4arrayobject.cpp
+++ b/src/qml/jsruntime/qv4arrayobject.cpp
@@ -35,6 +35,7 @@
#include "qv4sparsearray_p.h"
#include "qv4objectproto_p.h"
#include "qv4scopedvalue_p.h"
+#include "qv4runtime_p.h"
using namespace QV4;
@@ -57,7 +58,7 @@ ReturnedValue ArrayCtor::construct(Managed *m, CallData *callData)
len = callData->args[0].asArrayLength(&ok);
if (!ok)
- return v4->currentContext()->throwRangeError(callData->args[0]);
+ return v4->throwRangeError(callData->args[0]);
if (len < 0x1000)
a->arrayReserve(len);
@@ -285,7 +286,7 @@ ReturnedValue ArrayPrototype::method_push(CallContext *ctx)
instance->put(ctx->d()->engine->id_length, ScopedValue(scope, Primitive::fromDouble(newLen)));
else {
ScopedString str(scope, ctx->d()->engine->newString(QStringLiteral("Array.prototype.push: Overflow")));
- return ctx->throwRangeError(str);
+ return ctx->engine()->throwRangeError(str);
}
return Encode(newLen);
}
@@ -690,7 +691,7 @@ ReturnedValue ArrayPrototype::method_every(CallContext *ctx)
Scoped<FunctionObject> callback(scope, ctx->argument(0));
if (!callback)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
ScopedCallData callData(scope, 3);
callData->args[2] = instance;
@@ -724,7 +725,7 @@ ReturnedValue ArrayPrototype::method_some(CallContext *ctx)
Scoped<FunctionObject> callback(scope, ctx->argument(0));
if (!callback)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
ScopedCallData callData(scope, 3);
callData->thisObject = ctx->argument(1);
@@ -758,7 +759,7 @@ ReturnedValue ArrayPrototype::method_forEach(CallContext *ctx)
Scoped<FunctionObject> callback(scope, ctx->argument(0));
if (!callback)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
ScopedCallData callData(scope, 3);
callData->thisObject = ctx->argument(1);
@@ -789,7 +790,7 @@ ReturnedValue ArrayPrototype::method_map(CallContext *ctx)
Scoped<FunctionObject> callback(scope, ctx->argument(0));
if (!callback)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
Scoped<ArrayObject> a(scope, ctx->d()->engine->newArrayObject());
a->arrayReserve(len);
@@ -826,7 +827,7 @@ ReturnedValue ArrayPrototype::method_filter(CallContext *ctx)
Scoped<FunctionObject> callback(scope, ctx->argument(0));
if (!callback)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
Scoped<ArrayObject> a(scope, ctx->d()->engine->newArrayObject());
a->arrayReserve(len);
@@ -867,7 +868,7 @@ ReturnedValue ArrayPrototype::method_reduce(CallContext *ctx)
Scoped<FunctionObject> callback(scope, ctx->argument(0));
if (!callback)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
uint k = 0;
ScopedValue acc(scope);
@@ -884,7 +885,7 @@ ReturnedValue ArrayPrototype::method_reduce(CallContext *ctx)
++k;
}
if (!kPresent)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
}
ScopedCallData callData(scope, 4);
@@ -917,11 +918,11 @@ ReturnedValue ArrayPrototype::method_reduceRight(CallContext *ctx)
Scoped<FunctionObject> callback(scope, ctx->argument(0));
if (!callback)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
if (len == 0) {
if (ctx->d()->callData->argc == 1)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
return ctx->argument(1);
}
@@ -939,7 +940,7 @@ ReturnedValue ArrayPrototype::method_reduceRight(CallContext *ctx)
--k;
}
if (!kPresent)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
}
ScopedCallData callData(scope, 4);
diff --git a/src/qml/jsruntime/qv4booleanobject.cpp b/src/qml/jsruntime/qv4booleanobject.cpp
index b58fcbe709..17f638426a 100644
--- a/src/qml/jsruntime/qv4booleanobject.cpp
+++ b/src/qml/jsruntime/qv4booleanobject.cpp
@@ -78,7 +78,7 @@ ReturnedValue BooleanPrototype::method_toString(CallContext *ctx)
Scope scope(ctx);
Scoped<BooleanObject> thisObject(scope, ctx->d()->callData->thisObject);
if (!thisObject)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
result = thisObject->value().booleanValue();
}
@@ -93,7 +93,7 @@ ReturnedValue BooleanPrototype::method_valueOf(CallContext *ctx)
Scope scope(ctx);
Scoped<BooleanObject> thisObject(scope, ctx->d()->callData->thisObject);
if (!thisObject)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
return thisObject->value().asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp
index 5ca47a80b1..2dc8e8b608 100644
--- a/src/qml/jsruntime/qv4context.cpp
+++ b/src/qml/jsruntime/qv4context.cpp
@@ -48,7 +48,7 @@ DEFINE_MANAGED_VTABLE(CallContext);
DEFINE_MANAGED_VTABLE(WithContext);
DEFINE_MANAGED_VTABLE(GlobalContext);
-HeapObject *ExecutionContext::newCallContext(FunctionObject *function, CallData *callData)
+Returned<CallContext> *ExecutionContext::newCallContext(FunctionObject *function, CallData *callData)
{
Q_ASSERT(function->function());
@@ -78,24 +78,25 @@ HeapObject *ExecutionContext::newCallContext(FunctionObject *function, CallData
std::fill(c->callData->args + c->callData->argc, c->callData->args + compiledFunction->nFormals, Primitive::undefinedValue());
c->callData->argc = qMax((uint)callData->argc, compiledFunction->nFormals);
- return c;
+ return Returned<CallContext>::create(c);
}
-WithContext *ExecutionContext::newWithContext(Object *with)
+Returned<WithContext> *ExecutionContext::newWithContext(Object *with)
{
return d()->engine->memoryManager->alloc<WithContext>(d()->engine, with);
}
-CatchContext *ExecutionContext::newCatchContext(String *exceptionVarName, const ValueRef exceptionValue)
+Returned<CatchContext> *ExecutionContext::newCatchContext(String *exceptionVarName, const ValueRef exceptionValue)
{
return d()->engine->memoryManager->alloc<CatchContext>(d()->engine, exceptionVarName, exceptionValue);
}
-CallContext *ExecutionContext::newQmlContext(FunctionObject *f, Object *qml)
+Returned<CallContext> *ExecutionContext::newQmlContext(FunctionObject *f, Object *qml)
{
- CallContext *c = reinterpret_cast<CallContext*>(d()->engine->memoryManager->allocManaged(requiredMemoryForExecutionContect(f, 0)));
+ Scope scope(this);
+ Scoped<CallContext> c(scope, static_cast<CallContext*>(d()->engine->memoryManager->allocManaged(requiredMemoryForExecutionContect(f, 0))));
new (c->d()) CallContext::Data(d()->engine, qml, f);
- return c;
+ return c.asReturned();
}
@@ -236,7 +237,7 @@ bool ExecutionContext::deleteProperty(String *name)
}
if (d()->strictMode)
- throwSyntaxError(QStringLiteral("Can't delete property %1").arg(name->toQString()));
+ engine()->throwSyntaxError(QStringLiteral("Can't delete property %1").arg(name->toQString()));
return true;
}
@@ -245,35 +246,35 @@ bool CallContext::needsOwnArguments() const
return d()->function->needsActivation() || d()->callData->argc < static_cast<int>(d()->function->formalParameterCount());
}
-void ExecutionContext::markObjects(Managed *m, ExecutionEngine *engine)
+void ExecutionContext::markObjects(HeapObject *m, ExecutionEngine *engine)
{
- ExecutionContext *ctx = static_cast<ExecutionContext *>(m);
+ ExecutionContext::Data *ctx = static_cast<ExecutionContext::Data *>(m);
- if (ctx->d()->outer)
- ctx->d()->outer->mark(engine);
+ if (ctx->outer)
+ ctx->outer->mark(engine);
// ### shouldn't need these 3 lines
- ctx->d()->callData->thisObject.mark(engine);
- for (int arg = 0; arg < ctx->d()->callData->argc; ++arg)
- ctx->d()->callData->args[arg].mark(engine);
-
- if (ctx->d()->type >= Type_CallContext) {
- QV4::CallContext *c = static_cast<CallContext *>(ctx);
- for (unsigned local = 0, lastLocal = c->d()->function->varCount(); local < lastLocal; ++local)
- c->d()->locals[local].mark(engine);
- if (c->d()->activation)
- c->d()->activation->mark(engine);
- c->d()->function->mark(engine);
- } else if (ctx->d()->type == Type_WithContext) {
- WithContext *w = static_cast<WithContext *>(ctx);
- w->d()->withObject->mark(engine);
- } else if (ctx->d()->type == Type_CatchContext) {
- CatchContext *c = static_cast<CatchContext *>(ctx);
- c->d()->exceptionVarName->mark(engine);
- c->d()->exceptionValue.mark(engine);
- } else if (ctx->d()->type == Type_GlobalContext) {
- GlobalContext *g = static_cast<GlobalContext *>(ctx);
- g->d()->global->mark(engine);
+ ctx->callData->thisObject.mark(engine);
+ for (int arg = 0; arg < ctx->callData->argc; ++arg)
+ ctx->callData->args[arg].mark(engine);
+
+ if (ctx->type >= Type_CallContext) {
+ QV4::CallContext::Data *c = static_cast<CallContext::Data *>(ctx);
+ for (unsigned local = 0, lastLocal = c->function->varCount(); local < lastLocal; ++local)
+ c->locals[local].mark(engine);
+ if (c->activation)
+ c->activation->mark(engine);
+ c->function->mark(engine);
+ } else if (ctx->type == Type_WithContext) {
+ WithContext::Data *w = static_cast<WithContext::Data *>(ctx);
+ w->withObject->mark(engine);
+ } else if (ctx->type == Type_CatchContext) {
+ CatchContext::Data *c = static_cast<CatchContext::Data *>(ctx);
+ c->exceptionVarName->mark(engine);
+ c->exceptionValue.mark(engine);
+ } else if (ctx->type == Type_GlobalContext) {
+ GlobalContext::Data *g = static_cast<GlobalContext::Data *>(ctx);
+ g->global->mark(engine);
}
}
@@ -327,7 +328,7 @@ void ExecutionContext::setProperty(String *name, const ValueRef value)
}
if (d()->strictMode || name->equals(d()->engine->id_this.getPointer())) {
ScopedValue n(scope, name->asReturnedValue());
- throwReferenceError(n);
+ engine()->throwReferenceError(n);
return;
}
d()->engine->globalObject->put(name, value);
@@ -394,7 +395,7 @@ ReturnedValue ExecutionContext::getProperty(String *name)
}
}
ScopedValue n(scope, name);
- return throwReferenceError(n);
+ return engine()->throwReferenceError(n);
}
ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Object *&base)
@@ -463,100 +464,10 @@ ReturnedValue ExecutionContext::getPropertyAndBase(String *name, Object *&base)
}
}
ScopedValue n(scope, name);
- return throwReferenceError(n);
-}
-
-
-ReturnedValue ExecutionContext::throwError(const ValueRef value)
-{
- return d()->engine->throwException(value);
-}
-
-ReturnedValue ExecutionContext::throwError(const QString &message)
-{
- Scope scope(this);
- ScopedValue v(scope, d()->engine->newString(message));
- v = d()->engine->newErrorObject(v);
- return throwError(v);
-}
-
-ReturnedValue ExecutionContext::throwSyntaxError(const QString &message, const QString &fileName, int line, int column)
-{
- Scope scope(this);
- Scoped<Object> error(scope, d()->engine->newSyntaxErrorObject(message, fileName, line, column));
- return throwError(error);
-}
-
-ReturnedValue ExecutionContext::throwSyntaxError(const QString &message)
-{
- Scope scope(this);
- Scoped<Object> error(scope, d()->engine->newSyntaxErrorObject(message));
- return throwError(error);
-}
-
-ReturnedValue ExecutionContext::throwTypeError()
-{
- Scope scope(this);
- Scoped<Object> error(scope, d()->engine->newTypeErrorObject(QStringLiteral("Type error")));
- return throwError(error);
-}
-
-ReturnedValue ExecutionContext::throwTypeError(const QString &message)
-{
- Scope scope(this);
- Scoped<Object> error(scope, d()->engine->newTypeErrorObject(message));
- return throwError(error);
-}
-
-ReturnedValue ExecutionContext::throwUnimplemented(const QString &message)
-{
- Scope scope(this);
- ScopedValue v(scope, d()->engine->newString(QStringLiteral("Unimplemented ") + message));
- v = d()->engine->newErrorObject(v);
- return throwError(v);
+ return engine()->throwReferenceError(n);
}
ReturnedValue ExecutionContext::catchException(StackTrace *trace)
{
return d()->engine->catchException(this, trace);
}
-
-ReturnedValue ExecutionContext::throwReferenceError(const ValueRef value)
-{
- Scope scope(this);
- Scoped<String> s(scope, value->toString(this));
- QString msg = s->toQString() + QStringLiteral(" is not defined");
- Scoped<Object> error(scope, d()->engine->newReferenceErrorObject(msg));
- return throwError(error);
-}
-
-ReturnedValue ExecutionContext::throwReferenceError(const QString &message, const QString &fileName, int line, int column)
-{
- Scope scope(this);
- QString msg = message;
- Scoped<Object> error(scope, d()->engine->newReferenceErrorObject(msg, fileName, line, column));
- return throwError(error);
-}
-
-ReturnedValue ExecutionContext::throwRangeError(const ValueRef value)
-{
- Scope scope(this);
- ScopedString s(scope, value->toString(this));
- QString msg = s->toQString() + QStringLiteral(" out of range");
- ScopedObject error(scope, d()->engine->newRangeErrorObject(msg));
- return throwError(error);
-}
-
-ReturnedValue ExecutionContext::throwRangeError(const QString &message)
-{
- Scope scope(this);
- ScopedObject error(scope, d()->engine->newRangeErrorObject(message));
- return throwError(error);
-}
-
-ReturnedValue ExecutionContext::throwURIError(const ValueRef msg)
-{
- Scope scope(this);
- ScopedObject error(scope, d()->engine->newURIErrorObject(msg));
- return throwError(error);
-}
diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h
index 74530e7ae9..a942c12f6c 100644
--- a/src/qml/jsruntime/qv4context_p.h
+++ b/src/qml/jsruntime/qv4context_p.h
@@ -42,20 +42,12 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
-struct Object;
-struct ExecutionEngine;
-struct DeclarativeEnvironment;
-struct Lookup;
-struct Function;
-struct ValueRef;
-
namespace CompiledData {
struct CompilationUnit;
struct Function;
}
struct CallContext;
-struct CallContext;
struct CatchContext;
struct WithContext;
@@ -127,26 +119,13 @@ struct Q_QML_EXPORT ExecutionContext : public Managed
engine->current = this;
}
- HeapObject *newCallContext(FunctionObject *f, CallData *callData);
- WithContext *newWithContext(Object *with);
- CatchContext *newCatchContext(String *exceptionVarName, const ValueRef exceptionValue);
- CallContext *newQmlContext(FunctionObject *f, Object *qml);
+ Returned<CallContext> *newCallContext(FunctionObject *f, CallData *callData);
+ Returned<WithContext> *newWithContext(Object *with);
+ Returned<CatchContext> *newCatchContext(String *exceptionVarName, const ValueRef exceptionValue);
+ Returned<CallContext> *newQmlContext(FunctionObject *f, Object *qml);
void createMutableBinding(String *name, bool deletable);
- ReturnedValue throwError(const QV4::ValueRef value);
- ReturnedValue throwError(const QString &message);
- ReturnedValue throwSyntaxError(const QString &message);
- ReturnedValue throwSyntaxError(const QString &message, const QString &fileName, int lineNumber, int column);
- ReturnedValue throwTypeError();
- ReturnedValue throwTypeError(const QString &message);
- ReturnedValue throwReferenceError(const ValueRef value);
- ReturnedValue throwReferenceError(const QString &value, const QString &fileName, int lineNumber, int column);
- ReturnedValue throwRangeError(const ValueRef value);
- ReturnedValue throwRangeError(const QString &message);
- ReturnedValue throwURIError(const ValueRef msg);
- ReturnedValue throwUnimplemented(const QString &message);
-
void setProperty(String *name, const ValueRef value);
ReturnedValue getProperty(String *name);
ReturnedValue getPropertyAndBase(String *name, Object *&base);
@@ -158,7 +137,7 @@ struct Q_QML_EXPORT ExecutionContext : public Managed
inline CallContext *asCallContext();
inline const CallContext *asCallContext() const;
- static void markObjects(Managed *m, ExecutionEngine *e);
+ static void markObjects(HeapObject *m, ExecutionEngine *e);
};
struct CallContext : public ExecutionContext
diff --git a/src/qml/jsruntime/qv4dataview.cpp b/src/qml/jsruntime/qv4dataview.cpp
new file mode 100644
index 0000000000..11cb04e22f
--- /dev/null
+++ b/src/qml/jsruntime/qv4dataview.cpp
@@ -0,0 +1,316 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qv4dataview_p.h"
+#include "qv4arraybuffer_p.h"
+
+#include "qendian.h"
+
+using namespace QV4;
+
+DEFINE_OBJECT_VTABLE(DataViewCtor);
+DEFINE_OBJECT_VTABLE(DataView);
+
+DataViewCtor::Data::Data(ExecutionContext *scope)
+ : FunctionObject::Data(scope, QStringLiteral("DataView"))
+{
+ setVTable(staticVTable());
+}
+
+ReturnedValue DataViewCtor::construct(Managed *m, CallData *callData)
+{
+ Scope scope(m->engine());
+ Scoped<ArrayBuffer> buffer(scope, callData->argument(0));
+ if (!buffer)
+ return scope.engine->throwTypeError();
+
+ double bo = callData->argc > 1 ? callData->args[1].toNumber() : 0;
+ uint byteOffset = (uint)bo;
+ uint bufferLength = buffer->d()->data->size;
+ double bl = callData->argc < 3 || callData->args[2].isUndefined() ? (bufferLength - bo) : callData->args[2].toNumber();
+ uint byteLength = (uint)bl;
+ if (bo != byteOffset || bl != byteLength || byteOffset + byteLength > bufferLength)
+ return scope.engine->throwRangeError(QStringLiteral("DataView: constructor arguments out of range"));
+
+ Scoped<DataView> a(scope, scope.engine->memoryManager->alloc<DataView>(scope.engine));
+ a->d()->buffer = buffer;
+ a->d()->byteLength = byteLength;
+ a->d()->byteOffset = byteOffset;
+ return a.asReturnedValue();
+
+}
+
+ReturnedValue DataViewCtor::call(Managed *that, CallData *callData)
+{
+ return construct(that, callData);
+}
+
+
+DataView::Data::Data(ExecutionEngine *e)
+ : Object::Data(e->dataViewClass),
+ buffer(0),
+ byteLength(0),
+ byteOffset(0)
+{
+}
+
+
+void DataView::markObjects(HeapObject *that, ExecutionEngine *e)
+{
+ DataView::Data *v = static_cast<DataView::Data *>(that);
+ v->buffer->mark(e);
+}
+
+void DataViewPrototype::init(ExecutionEngine *engine, Object *ctor)
+{
+ Scope scope(engine);
+ ScopedObject o(scope);
+ ctor->defineReadonlyProperty(engine->id_length, Primitive::fromInt32(3));
+ ctor->defineReadonlyProperty(engine->id_prototype, (o = this));
+ defineDefaultProperty(engine->id_constructor, (o = ctor));
+ defineAccessorProperty(QStringLiteral("buffer"), method_get_buffer, 0);
+ defineAccessorProperty(QStringLiteral("byteLength"), method_get_byteLength, 0);
+ defineAccessorProperty(QStringLiteral("byteOffset"), method_get_byteOffset, 0);
+
+ defineDefaultProperty(QStringLiteral("getInt8"), method_getChar<signed char>, 0);
+ defineDefaultProperty(QStringLiteral("getUInt8"), method_getChar<unsigned char>, 0);
+ defineDefaultProperty(QStringLiteral("getInt16"), method_get<short>, 0);
+ defineDefaultProperty(QStringLiteral("getUInt16"), method_get<unsigned short>, 0);
+ defineDefaultProperty(QStringLiteral("getInt32"), method_get<int>, 0);
+ defineDefaultProperty(QStringLiteral("getUInt32"), method_get<unsigned int>, 0);
+ defineDefaultProperty(QStringLiteral("getFloat32"), method_getFloat<float>, 0);
+ defineDefaultProperty(QStringLiteral("getFloat64"), method_getFloat<double>, 0);
+
+ defineDefaultProperty(QStringLiteral("setInt8"), method_setChar<signed char>, 0);
+ defineDefaultProperty(QStringLiteral("setUInt8"), method_setChar<unsigned char>, 0);
+ defineDefaultProperty(QStringLiteral("setInt16"), method_set<short>, 0);
+ defineDefaultProperty(QStringLiteral("setUInt16"), method_set<unsigned short>, 0);
+ defineDefaultProperty(QStringLiteral("setInt32"), method_set<int>, 0);
+ defineDefaultProperty(QStringLiteral("setUInt32"), method_set<unsigned int>, 0);
+ defineDefaultProperty(QStringLiteral("setFloat32"), method_setFloat<float>, 0);
+ defineDefaultProperty(QStringLiteral("setFloat64"), method_setFloat<double>, 0);
+}
+
+ReturnedValue DataViewPrototype::method_get_buffer(CallContext *ctx)
+{
+ Scope scope(ctx);
+ Scoped<DataView> v(scope, ctx->d()->callData->thisObject);
+ if (!v)
+ return scope.engine->throwTypeError();
+
+ return Encode(v->d()->buffer->asReturnedValue());
+}
+
+ReturnedValue DataViewPrototype::method_get_byteLength(CallContext *ctx)
+{
+ Scope scope(ctx);
+ Scoped<DataView> v(scope, ctx->d()->callData->thisObject);
+ if (!v)
+ return scope.engine->throwTypeError();
+
+ return Encode(v->d()->byteLength);
+}
+
+ReturnedValue DataViewPrototype::method_get_byteOffset(CallContext *ctx)
+{
+ Scope scope(ctx);
+ Scoped<DataView> v(scope, ctx->d()->callData->thisObject);
+ if (!v)
+ return scope.engine->throwTypeError();
+
+ return Encode(v->d()->byteOffset);
+}
+
+template <typename T>
+ReturnedValue DataViewPrototype::method_getChar(CallContext *ctx)
+{
+ Scope scope(ctx);
+ Scoped<DataView> v(scope, ctx->d()->callData->thisObject);
+ if (!v || ctx->d()->callData->argc < 1)
+ return scope.engine->throwTypeError();
+ double l = ctx->d()->callData->args[0].toNumber();
+ uint idx = (uint)l;
+ if (l != idx || idx + sizeof(T) > v->d()->byteLength)
+ return scope.engine->throwTypeError();
+ idx += v->d()->byteOffset;
+
+ T t = T(v->d()->buffer->d()->data->data()[idx]);
+
+ return Encode((int)t);
+}
+
+template <typename T>
+ReturnedValue DataViewPrototype::method_get(CallContext *ctx)
+{
+ Scope scope(ctx);
+ Scoped<DataView> v(scope, ctx->d()->callData->thisObject);
+ if (!v || ctx->d()->callData->argc < 1)
+ return scope.engine->throwTypeError();
+ double l = ctx->d()->callData->args[0].toNumber();
+ uint idx = (uint)l;
+ if (l != idx || idx + sizeof(T) > v->d()->byteLength)
+ return scope.engine->throwTypeError();
+ idx += v->d()->byteOffset;
+
+ bool littleEndian = ctx->d()->callData->argc < 2 ? false : ctx->d()->callData->args[1].toBoolean();
+
+ T t = littleEndian
+ ? qFromLittleEndian<T>((uchar *)v->d()->buffer->d()->data->data() + idx)
+ : qFromBigEndian<T>((uchar *)v->d()->buffer->d()->data->data() + idx);
+
+ return Encode(t);
+}
+
+template <typename T>
+ReturnedValue DataViewPrototype::method_getFloat(CallContext *ctx)
+{
+ Scope scope(ctx);
+ Scoped<DataView> v(scope, ctx->d()->callData->thisObject);
+ if (!v || ctx->d()->callData->argc < 1)
+ return scope.engine->throwTypeError();
+ double l = ctx->d()->callData->args[0].toNumber();
+ uint idx = (uint)l;
+ if (l != idx || idx + sizeof(T) > v->d()->byteLength)
+ return scope.engine->throwTypeError();
+ idx += v->d()->byteOffset;
+
+ bool littleEndian = ctx->d()->callData->argc < 2 ? false : ctx->d()->callData->args[1].toBoolean();
+
+ if (sizeof(T) == 4) {
+ // float
+ union {
+ uint i;
+ float f;
+ } u;
+ u.i = littleEndian
+ ? qFromLittleEndian<uint>((uchar *)v->d()->buffer->d()->data->data() + idx)
+ : qFromBigEndian<uint>((uchar *)v->d()->buffer->d()->data->data() + idx);
+ return Encode(u.f);
+ } else {
+ Q_ASSERT(sizeof(T) == 8);
+ union {
+ quint64 i;
+ double d;
+ } u;
+ u.i = littleEndian
+ ? qFromLittleEndian<quint64>((uchar *)v->d()->buffer->d()->data->data() + idx)
+ : qFromBigEndian<quint64>((uchar *)v->d()->buffer->d()->data->data() + idx);
+ return Encode(u.d);
+ }
+}
+
+template <typename T>
+ReturnedValue DataViewPrototype::method_setChar(CallContext *ctx)
+{
+ Scope scope(ctx);
+ Scoped<DataView> v(scope, ctx->d()->callData->thisObject);
+ if (!v || ctx->d()->callData->argc < 1)
+ return scope.engine->throwTypeError();
+ double l = ctx->d()->callData->args[0].toNumber();
+ uint idx = (uint)l;
+ if (l != idx || idx + sizeof(T) > v->d()->byteLength)
+ return scope.engine->throwTypeError();
+ idx += v->d()->byteOffset;
+
+ int val = ctx->d()->callData->argc >= 2 ? ctx->d()->callData->args[1].toInt32() : 0;
+ v->d()->buffer->d()->data->data()[idx] = (char)val;
+
+ return Encode::undefined();
+}
+
+template <typename T>
+ReturnedValue DataViewPrototype::method_set(CallContext *ctx)
+{
+ Scope scope(ctx);
+ Scoped<DataView> v(scope, ctx->d()->callData->thisObject);
+ if (!v || ctx->d()->callData->argc < 1)
+ return scope.engine->throwTypeError();
+ double l = ctx->d()->callData->args[0].toNumber();
+ uint idx = (uint)l;
+ if (l != idx || idx + sizeof(T) > v->d()->byteLength)
+ return scope.engine->throwTypeError();
+ idx += v->d()->byteOffset;
+
+ int val = ctx->d()->callData->argc >= 2 ? ctx->d()->callData->args[1].toInt32() : 0;
+
+ bool littleEndian = ctx->d()->callData->argc < 3 ? false : ctx->d()->callData->args[2].toBoolean();
+
+ if (littleEndian)
+ qToLittleEndian<T>(val, (uchar *)v->d()->buffer->d()->data->data() + idx);
+ else
+ qToBigEndian<T>(val, (uchar *)v->d()->buffer->d()->data->data() + idx);
+
+ return Encode::undefined();
+}
+
+template <typename T>
+ReturnedValue DataViewPrototype::method_setFloat(CallContext *ctx)
+{
+ Scope scope(ctx);
+ Scoped<DataView> v(scope, ctx->d()->callData->thisObject);
+ if (!v || ctx->d()->callData->argc < 1)
+ return scope.engine->throwTypeError();
+ double l = ctx->d()->callData->args[0].toNumber();
+ uint idx = (uint)l;
+ if (l != idx || idx + sizeof(T) > v->d()->byteLength)
+ return scope.engine->throwTypeError();
+ idx += v->d()->byteOffset;
+
+ double val = ctx->d()->callData->argc >= 2 ? ctx->d()->callData->args[1].toNumber() : qSNaN();
+ bool littleEndian = ctx->d()->callData->argc < 3 ? false : ctx->d()->callData->args[2].toBoolean();
+
+ if (sizeof(T) == 4) {
+ // float
+ union {
+ uint i;
+ float f;
+ } u;
+ u.f = val;
+ if (littleEndian)
+ qToLittleEndian(u.i, (uchar *)v->d()->buffer->d()->data->data() + idx);
+ else
+ qToBigEndian(u.i, (uchar *)v->d()->buffer->d()->data->data() + idx);
+ } else {
+ Q_ASSERT(sizeof(T) == 8);
+ union {
+ quint64 i;
+ double d;
+ } u;
+ u.d = val;
+ if (littleEndian)
+ qToLittleEndian(u.i, (uchar *)v->d()->buffer->d()->data->data() + idx);
+ else
+ qToBigEndian(u.i, (uchar *)v->d()->buffer->d()->data->data() + idx);
+ }
+ return Encode::undefined();
+}
diff --git a/src/qml/jsruntime/qv4dataview_p.h b/src/qml/jsruntime/qv4dataview_p.h
new file mode 100644
index 0000000000..b1c2e361f4
--- /dev/null
+++ b/src/qml/jsruntime/qv4dataview_p.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QV4DATAVIEW_H
+#define QV4DATAVIEW_H
+
+#include "qv4object_p.h"
+#include "qv4functionobject_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace QV4 {
+
+struct ArrayBuffer;
+
+struct DataViewCtor: FunctionObject
+{
+ struct Data : FunctionObject::Data {
+ Data(ExecutionContext *scope);
+ };
+
+ V4_OBJECT(FunctionObject)
+
+ static ReturnedValue construct(Managed *m, CallData *callData);
+ static ReturnedValue call(Managed *that, CallData *callData);
+};
+
+struct DataView : Object
+{
+ struct Data : Object::Data {
+ Data(ExecutionEngine *e);
+ ArrayBuffer *buffer;
+ uint byteLength;
+ uint byteOffset;
+ };
+ V4_OBJECT(Object)
+
+ static void markObjects(HeapObject *that, ExecutionEngine *e);
+};
+
+struct DataViewPrototype: Object
+{
+ void init(ExecutionEngine *engine, Object *ctor);
+
+ static ReturnedValue method_get_buffer(CallContext *ctx);
+ static ReturnedValue method_get_byteLength(CallContext *ctx);
+ static ReturnedValue method_get_byteOffset(CallContext *ctx);
+ template <typename T>
+ static ReturnedValue method_getChar(CallContext *ctx);
+ template <typename T>
+ static ReturnedValue method_get(CallContext *ctx);
+ template <typename T>
+ static ReturnedValue method_getFloat(CallContext *ctx);
+ template <typename T>
+ static ReturnedValue method_setChar(CallContext *ctx);
+ template <typename T>
+ static ReturnedValue method_set(CallContext *ctx);
+ template <typename T>
+ static ReturnedValue method_setFloat(CallContext *ctx);
+};
+
+
+} // namespace QV4
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp
index e00a705700..25727166a5 100644
--- a/src/qml/jsruntime/qv4dateobject.cpp
+++ b/src/qml/jsruntime/qv4dateobject.cpp
@@ -35,6 +35,8 @@
#include "qv4dateobject_p.h"
#include "qv4objectproto_p.h"
#include "qv4scopedvalue_p.h"
+#include "qv4runtime_p.h"
+
#include <QtCore/qnumeric.h>
#include <QtCore/qmath.h>
#include <QtCore/QDateTime>
@@ -762,7 +764,7 @@ double DatePrototype::getThisDate(ExecutionContext *ctx)
if (DateObject *thisObject = ctx->d()->callData->thisObject.asDateObject())
return thisObject->date().asDouble();
else {
- ctx->throwTypeError();
+ ctx->engine()->throwTypeError();
return 0;
}
}
@@ -998,7 +1000,7 @@ ReturnedValue DatePrototype::method_setTime(CallContext *ctx)
Scope scope(ctx);
Scoped<DateObject> self(scope, ctx->d()->callData->thisObject);
if (!self)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
double t = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
self->date().setDouble(TimeClip(t));
@@ -1010,7 +1012,7 @@ ReturnedValue DatePrototype::method_setMilliseconds(CallContext *ctx)
Scope scope(ctx);
Scoped<DateObject> self(scope, ctx->d()->callData->thisObject);
if (!self)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
double t = LocalTime(self->date().asDouble());
double ms = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
@@ -1022,7 +1024,7 @@ ReturnedValue DatePrototype::method_setUTCMilliseconds(CallContext *ctx)
{
DateObject *self = ctx->d()->callData->thisObject.asDateObject();
if (!self)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
double t = self->date().asDouble();
double ms = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
@@ -1034,7 +1036,7 @@ ReturnedValue DatePrototype::method_setSeconds(CallContext *ctx)
{
DateObject *self = ctx->d()->callData->thisObject.asDateObject();
if (!self)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
double t = LocalTime(self->date().asDouble());
double sec = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
@@ -1048,7 +1050,7 @@ ReturnedValue DatePrototype::method_setUTCSeconds(CallContext *ctx)
{
DateObject *self = ctx->d()->callData->thisObject.asDateObject();
if (!self)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
double t = self->date().asDouble();
double sec = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
@@ -1062,7 +1064,7 @@ ReturnedValue DatePrototype::method_setMinutes(CallContext *ctx)
{
DateObject *self = ctx->d()->callData->thisObject.asDateObject();
if (!self)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
double t = LocalTime(self->date().asDouble());
double min = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
@@ -1077,7 +1079,7 @@ ReturnedValue DatePrototype::method_setUTCMinutes(CallContext *ctx)
{
DateObject *self = ctx->d()->callData->thisObject.asDateObject();
if (!self)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
double t = self->date().asDouble();
double min = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
@@ -1092,7 +1094,7 @@ ReturnedValue DatePrototype::method_setHours(CallContext *ctx)
{
DateObject *self = ctx->d()->callData->thisObject.asDateObject();
if (!self)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
double t = LocalTime(self->date().asDouble());
double hour = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
@@ -1108,7 +1110,7 @@ ReturnedValue DatePrototype::method_setUTCHours(CallContext *ctx)
{
DateObject *self = ctx->d()->callData->thisObject.asDateObject();
if (!self)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
double t = self->date().asDouble();
double hour = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
@@ -1124,7 +1126,7 @@ ReturnedValue DatePrototype::method_setDate(CallContext *ctx)
{
DateObject *self = ctx->d()->callData->thisObject.asDateObject();
if (!self)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
double t = LocalTime(self->date().asDouble());
double date = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
@@ -1137,7 +1139,7 @@ ReturnedValue DatePrototype::method_setUTCDate(CallContext *ctx)
{
DateObject *self = ctx->d()->callData->thisObject.asDateObject();
if (!self)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
double t = self->date().asDouble();
double date = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
@@ -1150,7 +1152,7 @@ ReturnedValue DatePrototype::method_setMonth(CallContext *ctx)
{
DateObject *self = ctx->d()->callData->thisObject.asDateObject();
if (!self)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
double t = LocalTime(self->date().asDouble());
double month = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
@@ -1164,7 +1166,7 @@ ReturnedValue DatePrototype::method_setUTCMonth(CallContext *ctx)
{
DateObject *self = ctx->d()->callData->thisObject.asDateObject();
if (!self)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
double t = self->date().asDouble();
double month = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
@@ -1178,7 +1180,7 @@ ReturnedValue DatePrototype::method_setYear(CallContext *ctx)
{
DateObject *self = ctx->d()->callData->thisObject.asDateObject();
if (!self)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
double t = self->date().asDouble();
if (std::isnan(t))
@@ -1204,7 +1206,7 @@ ReturnedValue DatePrototype::method_setUTCFullYear(CallContext *ctx)
{
DateObject *self = ctx->d()->callData->thisObject.asDateObject();
if (!self)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
double t = self->date().asDouble();
double year = ctx->d()->callData->argc ? ctx->d()->callData->args[0].toNumber() : qSNaN();
@@ -1219,7 +1221,7 @@ ReturnedValue DatePrototype::method_setFullYear(CallContext *ctx)
{
DateObject *self = ctx->d()->callData->thisObject.asDateObject();
if (!self)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
double t = LocalTime(self->date().asDouble());
if (std::isnan(t))
@@ -1236,7 +1238,7 @@ ReturnedValue DatePrototype::method_toUTCString(CallContext *ctx)
{
DateObject *self = ctx->d()->callData->thisObject.asDateObject();
if (!self)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
double t = self->date().asDouble();
return ctx->d()->engine->newString(ToUTCString(t))->asReturnedValue();
@@ -1259,11 +1261,11 @@ ReturnedValue DatePrototype::method_toISOString(CallContext *ctx)
{
DateObject *self = ctx->d()->callData->thisObject.asDateObject();
if (!self)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
double t = self->date().asDouble();
if (!std::isfinite(t))
- return ctx->throwRangeError(ctx->d()->callData->thisObject);
+ return ctx->engine()->throwRangeError(ctx->d()->callData->thisObject);
QString result;
int year = (int)YearFromTime(t);
@@ -1307,7 +1309,7 @@ ReturnedValue DatePrototype::method_toJSON(CallContext *ctx)
FunctionObject *toIso = v->asFunctionObject();
if (!toIso)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
ScopedCallData callData(scope, 0);
callData->thisObject = ctx->d()->callData->thisObject;
diff --git a/src/qml/jsruntime/qv4debugging.cpp b/src/qml/jsruntime/qv4debugging.cpp
index bcf0d07719..c001b60295 100644
--- a/src/qml/jsruntime/qv4debugging.cpp
+++ b/src/qml/jsruntime/qv4debugging.cpp
@@ -38,6 +38,7 @@
#include "qv4instr_moth_p.h"
#include "qv4runtime_p.h"
#include "qv4script_p.h"
+#include "qv4objectiterator_p.h"
#include <iostream>
#include <algorithm>
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index ea075f9cbd..c47420583c 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -61,6 +61,9 @@
#include "qv4qobjectwrapper_p.h"
#include "qv4qmlextensions_p.h"
#include "qv4memberdata_p.h"
+#include "qv4arraybuffer_p.h"
+#include "qv4dataview_p.h"
+#include "qv4typedarray_p.h"
#include <QtCore/QTextStream>
#include <QDateTime>
@@ -87,7 +90,7 @@ static QBasicAtomicInt engineSerial = Q_BASIC_ATOMIC_INITIALIZER(1);
static ReturnedValue throwTypeError(CallContext *ctx)
{
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
}
const int MinimumStackSize = 256; // in kbytes
@@ -198,7 +201,9 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
// reserve space for the JS stack
// we allow it to grow to 2 times JSStackLimit, as we can overshoot due to garbage collection
// and ScopedValues allocated outside of JIT'ed methods.
- *jsStack = WTF::PageAllocation::allocate(2*JSStackLimit, WTF::OSAllocator::JSVMStackPages, true);
+ *jsStack = WTF::PageAllocation::allocate(2 * JSStackLimit, WTF::OSAllocator::JSVMStackPages,
+ /* writable */ true, /* executable */ false,
+ /* includesGuardPages */ true);
jsStackBase = (Value *)jsStack->base();
jsStackTop = jsStackBase;
@@ -252,6 +257,9 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
id_toString = newIdentifier(QStringLiteral("toString"));
id_destroy = newIdentifier(QStringLiteral("destroy"));
id_valueOf = newIdentifier(QStringLiteral("valueOf"));
+ id_byteLength = newIdentifier(QStringLiteral("byteLength"));
+ id_byteOffset = newIdentifier(QStringLiteral("byteOffset"));
+ id_buffer = newIdentifier(QStringLiteral("buffer"));
memberDataClass = InternalClass::create(this, MemberData::staticVTable(), 0);
@@ -361,7 +369,27 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
static_cast<URIErrorPrototype *>(uRIErrorPrototype.getPointer())->init(this, uRIErrorCtor.asObject());
static_cast<VariantPrototype *>(variantPrototype.getPointer())->init();
- static_cast<SequencePrototype *>(sequencePrototype.managed())->init();
+ sequencePrototype.cast<SequencePrototype>()->init();
+
+
+ // typed arrays
+
+ arrayBufferCtor = memoryManager->alloc<ArrayBufferCtor>(rootContext);
+ Scoped<ArrayBufferPrototype> arrayBufferPrototype(scope, memoryManager->alloc<ArrayBufferPrototype>(objectClass));
+ arrayBufferPrototype->init(this, arrayBufferCtor.asObject());
+ arrayBufferClass = InternalClass::create(this, ArrayBuffer::staticVTable(), arrayBufferPrototype);
+
+ dataViewCtor = memoryManager->alloc<DataViewCtor>(rootContext);
+ Scoped<DataViewPrototype> dataViewPrototype(scope, memoryManager->alloc<DataViewPrototype>(objectClass));
+ dataViewPrototype->init(this, dataViewCtor.asObject());
+ dataViewClass = InternalClass::create(this, DataView::staticVTable(), dataViewPrototype);
+
+ for (int i = 0; i < TypedArray::NTypes; ++i) {
+ typedArrayCtors[i] = memoryManager->alloc<TypedArrayCtor>(rootContext, TypedArray::Type(i));
+ Scoped<TypedArrayPrototype> typedArrayPrototype(scope, memoryManager->alloc<TypedArrayPrototype>(this, TypedArray::Type(i)));
+ typedArrayPrototype->init(this, static_cast<TypedArrayCtor *>(typedArrayCtors[i].asObject()));
+ typedArrayClasses[i] = InternalClass::create(this, TypedArray::staticVTable(), typedArrayPrototype);
+ }
//
// set up the global object
@@ -386,6 +414,12 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
globalObject->defineDefaultProperty(QStringLiteral("SyntaxError"), syntaxErrorCtor);
globalObject->defineDefaultProperty(QStringLiteral("TypeError"), typeErrorCtor);
globalObject->defineDefaultProperty(QStringLiteral("URIError"), uRIErrorCtor);
+
+ globalObject->defineDefaultProperty(QStringLiteral("ArrayBuffer"), arrayBufferCtor);
+ globalObject->defineDefaultProperty(QStringLiteral("DataView"), dataViewCtor);
+ ScopedString str(scope);
+ for (int i = 0; i < TypedArray::NTypes; ++i)
+ globalObject->defineDefaultProperty((str = typedArrayCtors[i].asFunctionObject()->name())->toQString(), typedArrayCtors[i]);
ScopedObject o(scope);
globalObject->defineDefaultProperty(QStringLiteral("Math"), (o = memoryManager->alloc<MathObject>(QV4::InternalClass::create(this, MathObject::staticVTable(), objectPrototype))));
globalObject->defineDefaultProperty(QStringLiteral("JSON"), (o = memoryManager->alloc<JsonObject>(QV4::InternalClass::create(this, JsonObject::staticVTable(), objectPrototype))));
@@ -410,7 +444,7 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory)
globalObject->defineDefaultProperty(QStringLiteral("unescape"), GlobalFunctions::method_unescape, 1);
Scoped<String> name(scope, newString(QStringLiteral("thrower")));
- thrower = ScopedFunctionObject(scope, BuiltinFunction::create(rootContext, name.getPointer(), throwTypeError)).getPointer();
+ thrower = ScopedFunctionObject(scope, BuiltinFunction::create(rootContext, name.getPointer(), ::throwTypeError)).getPointer();
}
ExecutionEngine::~ExecutionEngine()
@@ -474,11 +508,12 @@ InternalClass *ExecutionEngine::newClass(const InternalClass &other)
ExecutionContext *ExecutionEngine::pushGlobalContext()
{
- GlobalContext *g = memoryManager->alloc<GlobalContext>(this);
+ Scope scope(this);
+ Scoped<GlobalContext> g(scope, memoryManager->alloc<GlobalContext>(this));
g->d()->callData = rootContext->d()->callData;
- Q_ASSERT(currentContext() == g);
- return g;
+ Q_ASSERT(currentContext() == g.getPointer());
+ return g.getPointer();
}
@@ -665,10 +700,10 @@ Returned<Object> *ExecutionEngine::newVariantObject(const QVariant &v)
return o->asReturned<Object>();
}
-Returned<Object> *ExecutionEngine::newForEachIteratorObject(ExecutionContext *ctx, Object *o)
+Returned<Object> *ExecutionEngine::newForEachIteratorObject(Object *o)
{
Scope scope(this);
- ScopedObject obj(scope, memoryManager->alloc<ForEachIteratorObject>(ctx, o));
+ ScopedObject obj(scope, memoryManager->alloc<ForEachIteratorObject>(this, o));
return obj->asReturned<Object>();
}
@@ -850,7 +885,7 @@ void ExecutionEngine::markObjects()
Q_ASSERT(c->inUse());
if (!c->markBit()) {
c->d()->markBit = 1;
- c->markObjects(c, this);
+ c->markObjects(c->d(), this);
}
c = c->d()->parent;
}
@@ -887,6 +922,9 @@ void ExecutionEngine::markObjects()
id_toString->mark(this);
id_destroy->mark(this);
id_valueOf->mark(this);
+ id_byteLength->mark(this);
+ id_byteOffset->mark(this);
+ id_buffer->mark(this);
objectCtor.mark(this);
stringCtor.mark(this);
@@ -903,6 +941,10 @@ void ExecutionEngine::markObjects()
syntaxErrorCtor.mark(this);
typeErrorCtor.mark(this);
uRIErrorCtor.mark(this);
+ arrayBufferCtor.mark(this);
+ dataViewCtor.mark(this);
+ for (int i = 0; i < TypedArray::NTypes; ++i)
+ typedArrayCtors[i].mark(this);
sequencePrototype.mark(this);
exceptionValue.mark(this);
@@ -926,7 +968,7 @@ QmlExtensions *ExecutionEngine::qmlExtensions()
return m_qmlExtensions;
}
-ReturnedValue ExecutionEngine::throwException(const ValueRef value)
+ReturnedValue ExecutionEngine::throwError(const ValueRef value)
{
// we can get in here with an exception already set, as the runtime
// doesn't check after every operation that can throw.
@@ -964,6 +1006,92 @@ ReturnedValue ExecutionEngine::catchException(ExecutionContext *catchingContext,
return res;
}
+ReturnedValue ExecutionEngine::throwError(const QString &message)
+{
+ Scope scope(this);
+ ScopedValue v(scope, newString(message));
+ v = newErrorObject(v);
+ return throwError(v);
+}
+
+ReturnedValue ExecutionEngine::throwSyntaxError(const QString &message, const QString &fileName, int line, int column)
+{
+ Scope scope(this);
+ Scoped<Object> error(scope, newSyntaxErrorObject(message, fileName, line, column));
+ return throwError(error);
+}
+
+ReturnedValue ExecutionEngine::throwSyntaxError(const QString &message)
+{
+ Scope scope(this);
+ Scoped<Object> error(scope, newSyntaxErrorObject(message));
+ return throwError(error);
+}
+
+
+ReturnedValue ExecutionEngine::throwTypeError()
+{
+ Scope scope(this);
+ Scoped<Object> error(scope, newTypeErrorObject(QStringLiteral("Type error")));
+ return throwError(error);
+}
+
+ReturnedValue ExecutionEngine::throwTypeError(const QString &message)
+{
+ Scope scope(this);
+ Scoped<Object> error(scope, newTypeErrorObject(message));
+ return throwError(error);
+}
+
+ReturnedValue ExecutionEngine::throwReferenceError(const ValueRef value)
+{
+ Scope scope(this);
+ Scoped<String> s(scope, value->toString(this));
+ QString msg = s->toQString() + QStringLiteral(" is not defined");
+ Scoped<Object> error(scope, newReferenceErrorObject(msg));
+ return throwError(error);
+}
+
+ReturnedValue ExecutionEngine::throwReferenceError(const QString &message, const QString &fileName, int line, int column)
+{
+ Scope scope(this);
+ QString msg = message;
+ Scoped<Object> error(scope, newReferenceErrorObject(msg, fileName, line, column));
+ return throwError(error);
+}
+
+ReturnedValue ExecutionEngine::throwRangeError(const QString &message)
+{
+ Scope scope(this);
+ ScopedObject error(scope, newRangeErrorObject(message));
+ return throwError(error);
+}
+
+ReturnedValue ExecutionEngine::throwRangeError(const ValueRef value)
+{
+ Scope scope(this);
+ ScopedString s(scope, value->toString(this));
+ QString msg = s->toQString() + QStringLiteral(" out of range");
+ ScopedObject error(scope, newRangeErrorObject(msg));
+ return throwError(error);
+}
+
+ReturnedValue ExecutionEngine::throwURIError(const ValueRef msg)
+{
+ Scope scope(this);
+ ScopedObject error(scope, newURIErrorObject(msg));
+ return throwError(error);
+}
+
+ReturnedValue ExecutionEngine::throwUnimplemented(const QString &message)
+{
+ Scope scope(this);
+ ScopedValue v(scope, newString(QStringLiteral("Unimplemented ") + message));
+ v = newErrorObject(v);
+ return throwError(v);
+}
+
+
QQmlError ExecutionEngine::catchExceptionAsQmlError(ExecutionContext *context)
{
QV4::StackTrace trace;
diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h
index a4a40c2f41..1da54b1129 100644
--- a/src/qml/jsruntime/qv4engine_p.h
+++ b/src/qml/jsruntime/qv4engine_p.h
@@ -35,8 +35,7 @@
#include "qv4global_p.h"
#include "private/qv4isel_p.h"
-#include "qv4util_p.h"
-#include "qv4property_p.h"
+#include "qv4managed_p.h"
#include <private/qintrusivelist_p.h>
namespace WTF {
@@ -113,7 +112,7 @@ struct ExecutionContextSaver;
#define CHECK_STACK_LIMITS(v4) \
if ((v4->jsStackTop <= v4->jsStackLimit) && (reinterpret_cast<quintptr>(&v4) >= v4->cStackLimit || v4->recheckCStackLimits())) {} \
else \
- return v4->currentContext()->throwRangeError(QStringLiteral("Maximum call stack size exceeded."))
+ return v4->throwRangeError(QStringLiteral("Maximum call stack size exceeded."))
struct Q_QML_EXPORT ExecutionEngine
@@ -153,13 +152,13 @@ public:
jsStackTop -= nValues;
}
- void pushForGC(Managed *m) {
- *jsStackTop = Value::fromManaged(m);
+ void pushForGC(HeapObject *m) {
+ *jsStackTop = Value::fromHeapObject(m);
++jsStackTop;
}
- Managed *popForGC() {
+ HeapObject *popForGC() {
--jsStackTop;
- return jsStackTop->managed();
+ return jsStackTop->heapObject();
}
IdentifierTable *identifierTable;
@@ -189,6 +188,10 @@ public:
Value typeErrorCtor;
Value uRIErrorCtor;
Value sequencePrototype;
+ Value arrayBufferCtor;
+ Value dataViewCtor;
+ enum { NTypedArrayTypes = 9 }; // avoid header dependency
+ Value typedArrayCtors[NTypedArrayTypes];
InternalClassPool *classPool;
InternalClass *emptyClass;
@@ -224,6 +227,10 @@ public:
InternalClass *variantClass;
InternalClass *memberDataClass;
+ InternalClass *arrayBufferClass;
+ InternalClass *dataViewClass;
+ InternalClass *typedArrayClasses[NTypedArrayTypes]; // TypedArray::NValues, avoid including the header here
+
EvalFunction *evalFunction;
FunctionObject *thrower;
@@ -262,6 +269,9 @@ public:
StringValue id_toString;
StringValue id_destroy;
StringValue id_valueOf;
+ StringValue id_byteLength;
+ StringValue id_byteOffset;
+ StringValue id_buffer;
QSet<CompiledData::CompilationUnit*> compilationUnits;
@@ -330,7 +340,7 @@ public:
Returned<Object> *newVariantObject(const QVariant &v);
- Returned<Object> *newForEachIteratorObject(ExecutionContext *ctx, Object *o);
+ Returned<Object> *newForEachIteratorObject(Object *o);
Returned<Object> *qmlContextObject() const;
@@ -354,9 +364,21 @@ public:
Value exceptionValue;
StackTrace exceptionStackTrace;
- ReturnedValue throwException(const ValueRef value);
+ ReturnedValue throwError(const ValueRef value);
ReturnedValue catchException(ExecutionContext *catchingContext, StackTrace *trace);
+ ReturnedValue throwError(const QString &message);
+ ReturnedValue throwSyntaxError(const QString &message);
+ ReturnedValue throwSyntaxError(const QString &message, const QString &fileName, int lineNumber, int column);
+ ReturnedValue throwTypeError();
+ ReturnedValue throwTypeError(const QString &message);
+ ReturnedValue throwReferenceError(const ValueRef value);
+ ReturnedValue throwReferenceError(const QString &value, const QString &fileName, int lineNumber, int column);
+ ReturnedValue throwRangeError(const ValueRef value);
+ ReturnedValue throwRangeError(const QString &message);
+ ReturnedValue throwURIError(const ValueRef msg);
+ ReturnedValue throwUnimplemented(const QString &message);
+
// Use only inside catch(...) -- will re-throw if no JS exception
static QQmlError catchExceptionAsQmlError(QV4::ExecutionContext *context);
@@ -364,6 +386,7 @@ private:
QmlExtensions *m_qmlExtensions;
};
+// ### Remove me
inline
void Managed::mark(QV4::ExecutionEngine *engine)
{
@@ -371,6 +394,17 @@ void Managed::mark(QV4::ExecutionEngine *engine)
if (markBit())
return;
d()->markBit = 1;
+ engine->pushForGC(d());
+}
+
+
+inline
+void HeapObject::mark(QV4::ExecutionEngine *engine)
+{
+ Q_ASSERT(inUse);
+ if (markBit)
+ return;
+ markBit = 1;
engine->pushForGC(this);
}
diff --git a/src/qml/jsruntime/qv4errorobject.cpp b/src/qml/jsruntime/qv4errorobject.cpp
index d87083275d..ef664f2830 100644
--- a/src/qml/jsruntime/qv4errorobject.cpp
+++ b/src/qml/jsruntime/qv4errorobject.cpp
@@ -150,7 +150,7 @@ ReturnedValue ErrorObject::method_get_stack(CallContext *ctx)
Scope scope(ctx);
Scoped<ErrorObject> This(scope, ctx->d()->callData->thisObject);
if (!This)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
if (!This->d()->stack) {
QString trace;
for (int i = 0; i < This->d()->stackTrace.count(); ++i) {
@@ -170,11 +170,11 @@ ReturnedValue ErrorObject::method_get_stack(CallContext *ctx)
return This->d()->stack->asReturnedValue();
}
-void ErrorObject::markObjects(Managed *that, ExecutionEngine *e)
+void ErrorObject::markObjects(HeapObject *that, ExecutionEngine *e)
{
- ErrorObject *This = that->asErrorObject();
- if (This->d()->stack)
- This->d()->stack->mark(e);
+ ErrorObject::Data *This = static_cast<ErrorObject::Data *>(that);
+ if (This->stack)
+ This->stack->mark(e);
Object::markObjects(that, e);
}
@@ -365,7 +365,7 @@ ReturnedValue ErrorPrototype::method_toString(CallContext *ctx)
Object *o = ctx->d()->callData->thisObject.asObject();
if (!o)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
ScopedValue name(scope, o->get(ctx->d()->engine->id_name));
QString qname;
diff --git a/src/qml/jsruntime/qv4errorobject_p.h b/src/qml/jsruntime/qv4errorobject_p.h
index 47442ad985..ffbdafcc43 100644
--- a/src/qml/jsruntime/qv4errorobject_p.h
+++ b/src/qml/jsruntime/qv4errorobject_p.h
@@ -70,7 +70,7 @@ struct ErrorObject: Object {
SyntaxErrorObject *asSyntaxError();
static ReturnedValue method_get_stack(CallContext *ctx);
- static void markObjects(Managed *that, ExecutionEngine *e);
+ static void markObjects(HeapObject *that, ExecutionEngine *e);
static void destroy(Managed *that) { static_cast<ErrorObject *>(that)->d()->~Data(); }
};
diff --git a/src/qml/jsruntime/qv4function.cpp b/src/qml/jsruntime/qv4function.cpp
index c7fe2128ce..6bc48157c0 100644
--- a/src/qml/jsruntime/qv4function.cpp
+++ b/src/qml/jsruntime/qv4function.cpp
@@ -58,7 +58,7 @@ Function::Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit,
Scope scope(engine);
ScopedString s(scope);
for (int i = static_cast<int>(compiledFunction->nFormals - 1); i >= 0; --i) {
- String *arg = compilationUnit->runtimeStrings[formalsIndices[i]].asString();
+ String *arg = compilationUnit->runtimeStrings[formalsIndices[i]];
while (1) {
InternalClass *newClass = internalClass->addMember(arg, Attr_NotConfigurable);
if (newClass != internalClass) {
@@ -72,7 +72,7 @@ Function::Function(ExecutionEngine *engine, CompiledData::CompilationUnit *unit,
const quint32 *localsIndices = compiledFunction->localsTable();
for (quint32 i = 0; i < compiledFunction->nLocals; ++i) {
- String *local = compilationUnit->runtimeStrings[localsIndices[i]].asString();
+ String *local = compilationUnit->runtimeStrings[localsIndices[i]];
internalClass = internalClass->addMember(local, Attr_NotConfigurable);
}
}
diff --git a/src/qml/jsruntime/qv4function_p.h b/src/qml/jsruntime/qv4function_p.h
index 465489b83f..63bbb01e74 100644
--- a/src/qml/jsruntime/qv4function_p.h
+++ b/src/qml/jsruntime/qv4function_p.h
@@ -34,44 +34,12 @@
#define QV4FUNCTION_H
#include "qv4global_p.h"
-
-#include <QtCore/QVector>
-#include <QtCore/QByteArray>
-#include <QtCore/qurl.h>
-
-#include "qv4value_p.h"
#include <private/qv4compileddata_p.h>
-#include <private/qv4engine_p.h>
QT_BEGIN_NAMESPACE
namespace QV4 {
-struct String;
-struct Function;
-struct Object;
-struct FunctionObject;
-struct ExecutionContext;
-struct ExecutionEngine;
-class MemoryManager;
-
-struct ObjectPrototype;
-struct StringPrototype;
-struct NumberPrototype;
-struct BooleanPrototype;
-struct ArrayPrototype;
-struct FunctionPrototype;
-struct DatePrototype;
-struct ErrorPrototype;
-struct EvalErrorPrototype;
-struct RangeErrorPrototype;
-struct ReferenceErrorPrototype;
-struct SyntaxErrorPrototype;
-struct TypeErrorPrototype;
-struct URIErrorPrototype;
-struct InternalClass;
-struct Lookup;
-
struct Q_QML_EXPORT Function {
const CompiledData::Function *compiledFunction;
CompiledData::CompilationUnit *compilationUnit;
@@ -87,7 +55,7 @@ struct Q_QML_EXPORT Function {
~Function();
inline String *name() {
- return compilationUnit->runtimeStrings[compiledFunction->nameIndex].getPointer();
+ return compilationUnit->runtimeStrings[compiledFunction->nameIndex];
}
inline QString sourceFile() const { return compilationUnit->fileName(); }
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp
index f3ad8ef892..deb9e62591 100644
--- a/src/qml/jsruntime/qv4functionobject.cpp
+++ b/src/qml/jsruntime/qv4functionobject.cpp
@@ -48,15 +48,11 @@
#include <private/qqmljsast_p.h>
#include <private/qqmlcontextwrapper_p.h>
#include <private/qqmlengine_p.h>
-#include <qv4jsir_p.h>
#include <qv4codegen_p.h>
#include "private/qlocale_tools_p.h"
#include <QtCore/qmath.h>
#include <QtCore/QDebug>
-#include <cassert>
-#include <typeinfo>
-#include <iostream>
#include <algorithm>
#include "qv4alloca_p.h"
#include "qv4profiling_p.h"
@@ -147,7 +143,7 @@ ReturnedValue FunctionObject::newInstance()
ReturnedValue FunctionObject::construct(Managed *that, CallData *)
{
- that->internalClass()->engine->currentContext()->throwTypeError();
+ that->internalClass()->engine->throwTypeError();
return Encode::undefined();
}
@@ -156,23 +152,23 @@ ReturnedValue FunctionObject::call(Managed *, CallData *)
return Encode::undefined();
}
-void FunctionObject::markObjects(Managed *that, ExecutionEngine *e)
+void FunctionObject::markObjects(HeapObject *that, ExecutionEngine *e)
{
- FunctionObject *o = static_cast<FunctionObject *>(that);
- if (o->scope())
- o->scope()->mark(e);
+ FunctionObject::Data *o = static_cast<FunctionObject::Data *>(that);
+ if (o->scope)
+ o->scope->mark(e);
Object::markObjects(that, e);
}
-FunctionObject *FunctionObject::createScriptFunction(ExecutionContext *scope, Function *function, bool createProto)
+Returned<FunctionObject> *FunctionObject::createScriptFunction(ExecutionContext *scope, Function *function, bool createProto)
{
if (function->needsActivation() ||
function->compiledFunction->flags & CompiledData::Function::HasCatchOrWith ||
function->compiledFunction->nFormals > QV4::Global::ReservedArgumentCount ||
function->isNamedExpression())
- return scope->d()->engine->memoryManager->alloc<ScriptFunction>(scope, function);
- return scope->d()->engine->memoryManager->alloc<SimpleScriptFunction>(scope, function, createProto);
+ return scope->d()->engine->memoryManager->alloc<ScriptFunction>(scope, function)->as<FunctionObject>();
+ return scope->d()->engine->memoryManager->alloc<SimpleScriptFunction>(scope, function, createProto)->as<FunctionObject>();
}
DEFINE_OBJECT_VTABLE(FunctionCtor);
@@ -212,12 +208,12 @@ ReturnedValue FunctionCtor::construct(Managed *that, CallData *callData)
const bool parsed = parser.parseExpression();
if (!parsed)
- return v4->currentContext()->throwSyntaxError(QLatin1String("Parse error"));
+ return v4->throwSyntaxError(QLatin1String("Parse error"));
using namespace QQmlJS::AST;
FunctionExpression *fe = QQmlJS::AST::cast<FunctionExpression *>(parser.rootNode());
if (!fe)
- return v4->currentContext()->throwSyntaxError(QLatin1String("Parse error"));
+ return v4->throwSyntaxError(QLatin1String("Parse error"));
IR::Module module(v4->debugger != 0);
@@ -266,7 +262,7 @@ ReturnedValue FunctionPrototype::method_toString(CallContext *ctx)
{
FunctionObject *fun = ctx->d()->callData->thisObject.asFunctionObject();
if (!fun)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
return ctx->d()->engine->newString(QStringLiteral("function() { [code] }"))->asReturnedValue();
}
@@ -276,7 +272,7 @@ ReturnedValue FunctionPrototype::method_apply(CallContext *ctx)
Scope scope(ctx);
FunctionObject *o = ctx->d()->callData->thisObject.asFunctionObject();
if (!o)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
ScopedValue arg(scope, ctx->argument(1));
@@ -286,7 +282,7 @@ ReturnedValue FunctionPrototype::method_apply(CallContext *ctx)
if (!arr) {
len = 0;
if (!arg->isNullOrUndefined())
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
} else {
len = arr->getLength();
}
@@ -318,7 +314,7 @@ ReturnedValue FunctionPrototype::method_call(CallContext *ctx)
FunctionObject *o = ctx->d()->callData->thisObject.asFunctionObject();
if (!o)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
ScopedCallData callData(scope, ctx->d()->callData->argc ? ctx->d()->callData->argc - 1 : 0);
if (ctx->d()->callData->argc) {
@@ -334,7 +330,7 @@ ReturnedValue FunctionPrototype::method_bind(CallContext *ctx)
Scope scope(ctx);
Scoped<FunctionObject> target(scope, ctx->d()->callData->thisObject);
if (!target)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
ScopedValue boundThis(scope, ctx->argument(0));
Members boundArgs;
@@ -372,7 +368,7 @@ ReturnedValue ScriptFunction::construct(Managed *that, CallData *callData)
ExecutionContext *context = v4->currentContext();
callData->thisObject = obj.asReturnedValue();
- ExecutionContext *ctx = reinterpret_cast<ExecutionContext *>(context->newCallContext(f.getPointer(), callData));
+ Scoped<CallContext> ctx(scope, context->newCallContext(f.getPointer(), callData));
ExecutionContextSaver ctxSaver(context);
ScopedValue result(scope, Q_V4_PROFILE(v4, ctx, f->function()));
@@ -399,7 +395,7 @@ ReturnedValue ScriptFunction::call(Managed *that, CallData *callData)
ExecutionContext *context = v4->currentContext();
Scope scope(context);
- CallContext *ctx = reinterpret_cast<CallContext *>(context->newCallContext(f, callData));
+ Scoped<CallContext> ctx(scope, context->newCallContext(f, callData));
ExecutionContextSaver ctxSaver(context);
ScopedValue result(scope, Q_V4_PROFILE(v4, ctx, f->function()));
@@ -543,7 +539,7 @@ BuiltinFunction::Data::Data(ExecutionContext *scope, String *name, ReturnedValue
ReturnedValue BuiltinFunction::construct(Managed *f, CallData *)
{
- return f->internalClass()->engine->currentContext()->throwTypeError();
+ return f->internalClass()->engine->throwTypeError();
}
ReturnedValue BuiltinFunction::call(Managed *that, CallData *callData)
@@ -641,11 +637,11 @@ ReturnedValue BoundFunction::construct(Managed *that, CallData *dd)
return f->target()->construct(callData);
}
-void BoundFunction::markObjects(Managed *that, ExecutionEngine *e)
+void BoundFunction::markObjects(HeapObject *that, ExecutionEngine *e)
{
- BoundFunction *o = static_cast<BoundFunction *>(that);
- o->target()->mark(e);
- o->boundThis().mark(e);
- o->boundArgs().mark(e);
+ BoundFunction::Data *o = static_cast<BoundFunction::Data *>(that);
+ o->target->mark(e);
+ o->boundThis.mark(e);
+ o->boundArgs.mark(e);
FunctionObject::markObjects(that, e);
}
diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h
index c8edb765de..1ff8124e6a 100644
--- a/src/qml/jsruntime/qv4functionobject_p.h
+++ b/src/qml/jsruntime/qv4functionobject_p.h
@@ -33,59 +33,15 @@
#ifndef QV4FUNCTIONOBJECT_H
#define QV4FUNCTIONOBJECT_H
-#include "qv4global_p.h"
-#include "qv4runtime_p.h"
-#include "qv4engine_p.h"
-#include "qv4context_p.h"
#include "qv4object_p.h"
-#include "qv4string_p.h"
-#include "qv4managed_p.h"
-#include "qv4property_p.h"
#include "qv4function_p.h"
-#include "qv4objectiterator_p.h"
+#include "qv4context_p.h"
#include "qv4mm_p.h"
-#include <QtCore/QString>
-#include <QtCore/QHash>
-#include <QtCore/QScopedPointer>
-#include <cstdio>
-#include <cassert>
-
QT_BEGIN_NAMESPACE
namespace QV4 {
-struct Function;
-struct Object;
-struct BooleanObject;
-struct NumberObject;
-struct StringObject;
-struct ArrayObject;
-struct DateObject;
-struct FunctionObject;
-struct ErrorObject;
-struct ArgumentsObject;
-struct ExecutionContext;
-struct ExecutionEngine;
-class MemoryManager;
-
-struct ObjectPrototype;
-struct StringPrototype;
-struct NumberPrototype;
-struct BooleanPrototype;
-struct ArrayPrototype;
-struct FunctionPrototype;
-struct DatePrototype;
-struct ErrorPrototype;
-struct EvalErrorPrototype;
-struct RangeErrorPrototype;
-struct ReferenceErrorPrototype;
-struct SyntaxErrorPrototype;
-struct TypeErrorPrototype;
-struct URIErrorPrototype;
-struct InternalClass;
-struct Lookup;
-
struct Q_QML_EXPORT FunctionObject: Object {
struct Q_QML_PRIVATE_EXPORT Data : Object::Data {
Data(ExecutionContext *scope, String *name, bool createProto = false);
@@ -138,7 +94,7 @@ struct Q_QML_EXPORT FunctionObject: Object {
return v.asFunctionObject();
}
- static FunctionObject *createScriptFunction(ExecutionContext *scope, Function *function, bool createProto = true);
+ static Returned<FunctionObject> *createScriptFunction(ExecutionContext *scope, Function *function, bool createProto = true);
ReturnedValue protoProperty() { return memberData()[Index_Prototype].asReturnedValue(); }
@@ -146,7 +102,7 @@ struct Q_QML_EXPORT FunctionObject: Object {
bool strictMode() const { return d()->strictMode; }
bool bindingKeyFlag() const { return d()->bindingKeyFlag; }
- static void markObjects(Managed *that, ExecutionEngine *e);
+ static void markObjects(HeapObject *that, ExecutionEngine *e);
};
template<>
@@ -188,7 +144,7 @@ struct Q_QML_EXPORT BuiltinFunction: FunctionObject {
};
V4_OBJECT(FunctionObject)
- static BuiltinFunction *create(ExecutionContext *scope, String *name, ReturnedValue (*code)(CallContext *))
+ static Returned<BuiltinFunction> *create(ExecutionContext *scope, String *name, ReturnedValue (*code)(CallContext *))
{
return scope->engine()->memoryManager->alloc<BuiltinFunction>(scope, name, code);
}
@@ -214,7 +170,7 @@ struct IndexedBuiltinFunction: FunctionObject
static ReturnedValue construct(Managed *m, CallData *)
{
- return m->engine()->currentContext()->throwTypeError();
+ return m->engine()->throwTypeError();
}
static ReturnedValue call(Managed *that, CallData *callData);
@@ -253,7 +209,7 @@ struct BoundFunction: FunctionObject {
};
V4_OBJECT(FunctionObject)
- static BoundFunction *create(ExecutionContext *scope, FunctionObject *target, const ValueRef boundThis, const QV4::Members &boundArgs)
+ static Returned<BoundFunction> *create(ExecutionContext *scope, FunctionObject *target, const ValueRef boundThis, const QV4::Members &boundArgs)
{
return scope->engine()->memoryManager->alloc<BoundFunction>(scope, target, boundThis, boundArgs);
}
@@ -265,7 +221,7 @@ struct BoundFunction: FunctionObject {
static ReturnedValue construct(Managed *, CallData *d);
static ReturnedValue call(Managed *that, CallData *dd);
- static void markObjects(Managed *that, ExecutionEngine *e);
+ static void markObjects(HeapObject *that, ExecutionEngine *e);
};
}
diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h
index 81f1240d89..71f217395b 100644
--- a/src/qml/jsruntime/qv4global_p.h
+++ b/src/qml/jsruntime/qv4global_p.h
@@ -126,6 +126,10 @@ struct ScriptFunction;
struct InternalClass;
struct Property;
struct Value;
+struct Lookup;
+struct HeapObject;
+struct ArrayData;
+struct ManagedVTable;
struct BooleanObject;
struct NumberObject;
@@ -146,6 +150,7 @@ struct QObjectWrapper;
// It will be returned in rax on x64, [eax,edx] on x86 and [r0,r1] on arm
typedef quint64 ReturnedValue;
struct CallData;
+struct Scope;
struct ScopedValue;
struct ValueRef;
template<typename T> struct Scoped;
diff --git a/src/qml/jsruntime/qv4globalobject.cpp b/src/qml/jsruntime/qv4globalobject.cpp
index 49032e5bcf..e194460bfd 100644
--- a/src/qml/jsruntime/qv4globalobject.cpp
+++ b/src/qml/jsruntime/qv4globalobject.cpp
@@ -584,7 +584,7 @@ ReturnedValue GlobalFunctions::method_decodeURI(CallContext *context)
if (!ok) {
Scope scope(context);
ScopedString s(scope, context->d()->engine->newString(QStringLiteral("malformed URI sequence")));
- return context->throwURIError(s);
+ return context->engine()->throwURIError(s);
}
return context->d()->engine->newString(out)->asReturnedValue();
@@ -602,7 +602,7 @@ ReturnedValue GlobalFunctions::method_decodeURIComponent(CallContext *context)
if (!ok) {
Scope scope(context);
ScopedString s(scope, context->d()->engine->newString(QStringLiteral("malformed URI sequence")));
- return context->throwURIError(s);
+ return context->engine()->throwURIError(s);
}
return context->d()->engine->newString(out)->asReturnedValue();
@@ -620,7 +620,7 @@ ReturnedValue GlobalFunctions::method_encodeURI(CallContext *context)
if (!ok) {
Scope scope(context);
ScopedString s(scope, context->d()->engine->newString(QStringLiteral("malformed URI sequence")));
- return context->throwURIError(s);
+ return context->engine()->throwURIError(s);
}
return context->d()->engine->newString(out)->asReturnedValue();
@@ -638,7 +638,7 @@ ReturnedValue GlobalFunctions::method_encodeURIComponent(CallContext *context)
if (!ok) {
Scope scope(context);
ScopedString s(scope, context->d()->engine->newString(QStringLiteral("malformed URI sequence")));
- return context->throwURIError(s);
+ return context->engine()->throwURIError(s);
}
return context->d()->engine->newString(out)->asReturnedValue();
diff --git a/src/qml/jsruntime/qv4identifiertable.cpp b/src/qml/jsruntime/qv4identifiertable.cpp
index d7ed7a8db0..5554b68db3 100644
--- a/src/qml/jsruntime/qv4identifiertable.cpp
+++ b/src/qml/jsruntime/qv4identifiertable.cpp
@@ -121,7 +121,8 @@ String *IdentifierTable::insertString(const QString &s)
idx %= alloc;
}
- String *str = engine->newString(s)->getPointer();
+ Returned<String> *_s = engine->newString(s);
+ String *str = _s->getPointer();
addEntry(str);
return str;
}
diff --git a/src/qml/jsruntime/qv4identifiertable_p.h b/src/qml/jsruntime/qv4identifiertable_p.h
index 6ae2ec06d6..cc792fa3b4 100644
--- a/src/qml/jsruntime/qv4identifiertable_p.h
+++ b/src/qml/jsruntime/qv4identifiertable_p.h
@@ -78,7 +78,7 @@ public:
continue;
entry->d()->markBit = 1;
Q_ASSERT(entry->internalClass()->vtable->markObjects);
- entry->internalClass()->vtable->markObjects(entry, e);
+ entry->internalClass()->vtable->markObjects(entry->d(), e);
}
}
};
diff --git a/src/qml/jsruntime/qv4internalclass_p.h b/src/qml/jsruntime/qv4internalclass_p.h
index 06feea1d5a..972c341992 100644
--- a/src/qml/jsruntime/qv4internalclass_p.h
+++ b/src/qml/jsruntime/qv4internalclass_p.h
@@ -33,9 +33,9 @@
#ifndef QV4INTERNALCLASS_H
#define QV4INTERNALCLASS_H
-#include <QHash>
-#include <QVector>
#include "qv4global_p.h"
+
+#include <QHash>
#include <private/qqmljsmemorypool_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp
index 268559dec8..74cf26c381 100644
--- a/src/qml/jsruntime/qv4jsonobject.cpp
+++ b/src/qml/jsruntime/qv4jsonobject.cpp
@@ -37,6 +37,8 @@
#include <qv4booleanobject_p.h>
#include <qv4objectiterator_p.h>
#include <qv4scopedvalue_p.h>
+#include <qv4runtime_p.h>
+
#include <qjsondocument.h>
#include <qstack.h>
#include <qstringlist.h>
@@ -775,7 +777,7 @@ QString Stringify::makeMember(const QString &key, ValueRef v)
QString Stringify::JO(Object *o)
{
if (stack.contains(o)) {
- ctx->throwTypeError();
+ ctx->engine()->throwTypeError();
return QString();
}
@@ -832,7 +834,7 @@ QString Stringify::JO(Object *o)
QString Stringify::JA(ArrayObject *a)
{
if (stack.contains(a)) {
- ctx->throwTypeError();
+ ctx->engine()->throwTypeError();
return QString();
}
@@ -898,7 +900,7 @@ ReturnedValue JsonObject::method_parse(CallContext *ctx)
ScopedValue result(scope, parser.parse(&error));
if (error.error != QJsonParseError::NoError) {
DEBUG << "parse error" << error.errorString();
- return ctx->throwSyntaxError(QStringLiteral("JSON.parse: Parse error"));
+ return ctx->engine()->throwSyntaxError(QStringLiteral("JSON.parse: Parse error"));
}
return result.asReturnedValue();
diff --git a/src/qml/jsruntime/qv4lookup.cpp b/src/qml/jsruntime/qv4lookup.cpp
index 254666eca2..f7ebb62b8d 100644
--- a/src/qml/jsruntime/qv4lookup.cpp
+++ b/src/qml/jsruntime/qv4lookup.cpp
@@ -130,7 +130,7 @@ ReturnedValue Lookup::indexedGetterFallback(Lookup *l, const ValueRef object, co
if (object->isNullOrUndefined()) {
QString message = QStringLiteral("Cannot read property '%1' of %2").arg(index->toQStringNoThrow()).arg(object->toQStringNoThrow());
- return ctx->throwTypeError(message);
+ return ctx->engine()->throwTypeError(message);
}
o = RuntimeHelpers::convertToObject(ctx, object);
@@ -240,7 +240,7 @@ ReturnedValue Lookup::getterGeneric(QV4::Lookup *l, const ValueRef object)
switch (object->type()) {
case Value::Undefined_Type:
case Value::Null_Type:
- return engine->currentContext()->throwTypeError();
+ return engine->throwTypeError();
case Value::Boolean_Type:
proto = engine->booleanClass->prototype;
break;
@@ -598,7 +598,7 @@ ReturnedValue Lookup::globalGetterGeneric(Lookup *l, ExecutionContext *ctx)
}
Scope scope(ctx);
Scoped<String> n(scope, l->name);
- return ctx->throwReferenceError(n);
+ return ctx->engine()->throwReferenceError(n);
}
ReturnedValue Lookup::globalGetter0(Lookup *l, ExecutionContext *ctx)
diff --git a/src/qml/jsruntime/qv4managed.cpp b/src/qml/jsruntime/qv4managed.cpp
index c7327addfd..93286b3945 100644
--- a/src/qml/jsruntime/qv4managed.cpp
+++ b/src/qml/jsruntime/qv4managed.cpp
@@ -157,7 +157,7 @@ void Managed::setVTable(const ManagedVTable *vt)
d()->internalClass = internalClass()->changeVTable(vt);
}
-void Managed::Data::setVTable(const ManagedVTable *vt)
+void HeapObject::setVTable(const ManagedVTable *vt)
{
Q_ASSERT(internalClass);
internalClass = internalClass->changeVTable(vt);
diff --git a/src/qml/jsruntime/qv4managed_p.h b/src/qml/jsruntime/qv4managed_p.h
index e679017b7e..91dc0fb034 100644
--- a/src/qml/jsruntime/qv4managed_p.h
+++ b/src/qml/jsruntime/qv4managed_p.h
@@ -33,9 +33,6 @@
#ifndef QMLJS_MANAGED_H
#define QMLJS_MANAGED_H
-#include <QtCore/QString>
-#include <QtCore/QVector>
-#include <QtCore/QDebug>
#include "qv4global_p.h"
#include "qv4value_p.h"
#include "qv4internalclass_p.h"
@@ -45,7 +42,7 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
#define Q_MANAGED_CHECK \
- template <typename T> inline void qt_check_for_QMANAGED_macro(const T *_q_argument) const \
+ template <typename _T> inline void qt_check_for_QMANAGED_macro(const _T *_q_argument) const \
{ int i = qYouForgotTheQ_MANAGED_Macro(this, _q_argument); i = i + 1; }
template <typename T>
@@ -66,8 +63,8 @@ inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {}
typedef superClass SuperClass; \
static const QV4::ManagedVTable static_vtbl; \
static inline const QV4::ManagedVTable *staticVTable() { return &static_vtbl; } \
- template <typename T> \
- QV4::Returned<T> *asReturned() { return QV4::Returned<T>::create(this); } \
+ template <typename _T> \
+ QV4::Returned<_T> *asReturned() { return QV4::Returned<_T>::create(this); } \
V4_MANAGED_SIZE_TEST \
const Data *d() const { return &static_cast<const Data &>(Managed::data); } \
Data *d() { return &static_cast<Data &>(Managed::data); }
@@ -78,8 +75,8 @@ inline void qYouForgotTheQ_MANAGED_Macro(T1, T2) {}
typedef superClass SuperClass; \
static const QV4::ObjectVTable static_vtbl; \
static inline const QV4::ManagedVTable *staticVTable() { return &static_vtbl.managedVTable; } \
- template <typename T> \
- QV4::Returned<T> *asReturned() { return QV4::Returned<T>::create(this); } \
+ template <typename _T> \
+ QV4::Returned<_T> *asReturned() { return QV4::Returned<_T>::create(this); } \
V4_MANAGED_SIZE_TEST \
const Data *d() const { return &static_cast<const Data &>(Managed::data); } \
Data *d() { return &static_cast<Data &>(Managed::data); }
@@ -113,7 +110,7 @@ struct ManagedVTable
uint type : 8;
const char *className;
void (*destroy)(Managed *);
- void (*markObjects)(Managed *, ExecutionEngine *e);
+ void (*markObjects)(HeapObject *, ExecutionEngine *e);
bool (*isEqualTo)(Managed *m, Managed *other);
};
@@ -180,39 +177,10 @@ const QV4::ObjectVTable classname::static_vtbl = \
struct Q_QML_PRIVATE_EXPORT Managed
{
struct Q_QML_PRIVATE_EXPORT Data : HeapObject {
- Data() {}
+ Data() : HeapObject(0) {}
Data(InternalClass *internal)
- : internalClass(internal)
- , markBit(0)
- , inUse(1)
- , extensible(1)
- {
- // ####
-// Q_ASSERT(internal && internal->vtable);
- }
- InternalClass *internalClass;
- struct {
- uchar markBit : 1;
- uchar inUse : 1;
- uchar extensible : 1; // used by Object
- uchar _unused : 1;
- uchar needsActivation : 1; // used by FunctionObject
- uchar strictMode : 1; // used by FunctionObject
- uchar bindingKeyFlag : 1;
- uchar hasAccessorProperty : 1;
- uchar _type;
- mutable uchar subtype;
- uchar _flags;
- };
-
- void setVTable(const ManagedVTable *vt);
- ReturnedValue asReturnedValue() const {
- return reinterpret_cast<Managed *>(const_cast<Data *>(this))->asReturnedValue();
- }
-
- void *operator new(size_t, Managed *m) { return m; }
- void *operator new(size_t, Managed::Data *m) { return m; }
- void operator delete(void *, Managed::Data *) {}
+ : HeapObject(internal)
+ {}
};
Data data;
V4_MANAGED(Managed)
@@ -326,8 +294,8 @@ public:
void setVTable(const ManagedVTable *vt);
- bool isEqualTo(Managed *other)
- { return internalClass()->vtable->isEqualTo(this, other); }
+ bool isEqualTo(const Managed *other) const
+ { return internalClass()->vtable->isEqualTo(const_cast<Managed *>(this), const_cast<Managed *>(other)); }
static bool isEqualTo(Managed *m, Managed *other);
@@ -377,6 +345,20 @@ inline FunctionObject *managed_cast(Managed *m)
return m ? m->asFunctionObject() : 0;
}
+inline Value Value::fromManaged(Managed *m)
+{
+ if (!m)
+ return QV4::Primitive::undefinedValue();
+ Value v;
+#if QT_POINTER_SIZE == 8
+ v.m = &m->data;
+#else
+ v.tag = Managed_Type;
+ v.m = &m->data;
+#endif
+ return v;
+}
+
}
diff --git a/src/qml/jsruntime/qv4memberdata.cpp b/src/qml/jsruntime/qv4memberdata.cpp
index 405594ca9b..de226305f1 100644
--- a/src/qml/jsruntime/qv4memberdata.cpp
+++ b/src/qml/jsruntime/qv4memberdata.cpp
@@ -38,11 +38,11 @@ using namespace QV4;
DEFINE_MANAGED_VTABLE(MemberData);
-void MemberData::markObjects(Managed *that, ExecutionEngine *e)
+void MemberData::markObjects(HeapObject *that, ExecutionEngine *e)
{
- MemberData *m = static_cast<MemberData *>(that);
- for (uint i = 0; i < m->d()->size; ++i)
- m->d()->data[i].mark(e);
+ MemberData::Data *m = static_cast<MemberData::Data *>(that);
+ for (uint i = 0; i < m->size; ++i)
+ m->data[i].mark(e);
}
void Members::ensureIndex(QV4::ExecutionEngine *e, uint idx)
@@ -57,6 +57,6 @@ void Members::ensureIndex(QV4::ExecutionEngine *e, uint idx)
else
new (newMemberData) MemberData(e->memberDataClass);
newMemberData->d()->size = newAlloc;
- m = newMemberData;
+ m = &newMemberData->data;
}
}
diff --git a/src/qml/jsruntime/qv4memberdata_p.h b/src/qml/jsruntime/qv4memberdata_p.h
index 83732113a9..cc7b10ff81 100644
--- a/src/qml/jsruntime/qv4memberdata_p.h
+++ b/src/qml/jsruntime/qv4memberdata_p.h
@@ -54,7 +54,7 @@ struct MemberData : Managed
MemberData(QV4::InternalClass *ic) : Managed(ic) {}
Value &operator[] (uint idx) { return d()->data[idx]; }
- static void markObjects(Managed *that, ExecutionEngine *e);
+ static void markObjects(HeapObject *that, ExecutionEngine *e);
};
struct Members : Value
diff --git a/src/qml/jsruntime/qv4mm.cpp b/src/qml/jsruntime/qv4mm.cpp
index b9a4a55b4a..df439e1c5e 100644
--- a/src/qml/jsruntime/qv4mm.cpp
+++ b/src/qml/jsruntime/qv4mm.cpp
@@ -264,9 +264,9 @@ Managed *MemoryManager::allocData(std::size_t size)
static void drainMarkStack(QV4::ExecutionEngine *engine, Value *markBase)
{
while (engine->jsStackTop > markBase) {
- Managed *m = engine->popForGC();
- Q_ASSERT (m->internalClass()->vtable->markObjects);
- m->internalClass()->vtable->markObjects(m, engine);
+ HeapObject *h = engine->popForGC();
+ Q_ASSERT (h->internalClass->vtable->markObjects);
+ h->internalClass->vtable->markObjects(h, engine);
}
}
@@ -492,9 +492,9 @@ size_t MemoryManager::getUsedMem() const
char *chunkStart = reinterpret_cast<char *>(i->memory.base());
char *chunkEnd = chunkStart + i->memory.size() - i->chunkSize;
for (char *chunk = chunkStart; chunk <= chunkEnd; chunk += i->chunkSize) {
- Managed *m = reinterpret_cast<Managed *>(chunk);
+ Managed::Data *m = reinterpret_cast<Managed::Data *>(chunk);
Q_ASSERT((qintptr) chunk % 16 == 0);
- if (m->inUse())
+ if (m->inUse)
usedMem += i->chunkSize;
}
}
@@ -535,6 +535,11 @@ MemoryManager::~MemoryManager()
#endif
}
+ExecutionEngine *MemoryManager::engine() const
+{
+ return m_d->engine;
+}
+
void MemoryManager::setExecutionEngine(ExecutionEngine *engine)
{
m_d->engine = engine;
diff --git a/src/qml/jsruntime/qv4mm_p.h b/src/qml/jsruntime/qv4mm_p.h
index d5e28f7f84..f2267e5852 100644
--- a/src/qml/jsruntime/qv4mm_p.h
+++ b/src/qml/jsruntime/qv4mm_p.h
@@ -35,10 +35,8 @@
#define QV4GC_H
#include "qv4global_p.h"
-#include "qv4context_p.h"
#include "qv4value_inl_p.h"
-
-#include <QScopedPointer>
+#include "qv4scopedvalue_p.h"
//#define DETAILED_MM_STATS
@@ -96,57 +94,64 @@ public:
}
template <typename ManagedType>
- ManagedType *alloc()
+ Returned<ManagedType> *alloc()
{
- ManagedType *t = static_cast<ManagedType*>(allocManaged(sizeof(typename ManagedType::Data)));
+ Scope scope(engine());
+ Scoped<ManagedType> t(scope, static_cast<ManagedType*>(allocManaged(sizeof(typename ManagedType::Data))));
(void)new (t->d()) typename ManagedType::Data();
- return t;
+ return t.asReturned();
}
template <typename ManagedType, typename Arg1>
- ManagedType *alloc(Arg1 arg1)
+ Returned<ManagedType> *alloc(Arg1 arg1)
{
- ManagedType *t = static_cast<ManagedType*>(allocManaged(sizeof(typename ManagedType::Data)));
+ Scope scope(engine());
+ Scoped<ManagedType> t(scope, static_cast<ManagedType*>(allocManaged(sizeof(typename ManagedType::Data))));
(void)new (t->d()) typename ManagedType::Data(arg1);
- return t;
+ return t.asReturned();
}
template <typename ManagedType, typename Arg1, typename Arg2>
- ManagedType *alloc(Arg1 arg1, Arg2 arg2)
+ Returned<ManagedType> *alloc(Arg1 arg1, Arg2 arg2)
{
- ManagedType *t = static_cast<ManagedType*>(allocManaged(sizeof(typename ManagedType::Data)));
+ Scope scope(engine());
+ Scoped<ManagedType> t(scope, static_cast<ManagedType*>(allocManaged(sizeof(typename ManagedType::Data))));
(void)new (t->d()) typename ManagedType::Data(arg1, arg2);
- return t;
+ return t.asReturned();
}
template <typename ManagedType, typename Arg1, typename Arg2, typename Arg3>
- ManagedType *alloc(Arg1 arg1, Arg2 arg2, Arg3 arg3)
+ Returned<ManagedType> *alloc(Arg1 arg1, Arg2 arg2, Arg3 arg3)
{
- ManagedType *t = static_cast<ManagedType*>(allocManaged(sizeof(typename ManagedType::Data)));
+ Scope scope(engine());
+ Scoped<ManagedType> t(scope, static_cast<ManagedType*>(allocManaged(sizeof(typename ManagedType::Data))));
(void)new (t->d()) typename ManagedType::Data(arg1, arg2, arg3);
- return t;
+ return t.asReturned();
}
template <typename ManagedType, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
- ManagedType *alloc(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4)
+ Returned<ManagedType> *alloc(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4)
{
- ManagedType *t = static_cast<ManagedType*>(allocManaged(sizeof(typename ManagedType::Data)));
+ Scope scope(engine());
+ Scoped<ManagedType> t(scope, static_cast<ManagedType*>(allocManaged(sizeof(typename ManagedType::Data))));
(void)new (t->d()) typename ManagedType::Data(arg1, arg2, arg3, arg4);
- return t;
+ return t.asReturned();
}
template <typename ManagedType, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
- ManagedType *alloc(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5)
+ Returned<ManagedType> *alloc(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5)
{
- ManagedType *t = static_cast<ManagedType*>(allocManaged(sizeof(typename ManagedType::Data)));
+ Scope scope(engine());
+ Scoped<ManagedType> t(scope, static_cast<ManagedType*>(allocManaged(sizeof(typename ManagedType::Data))));
(void)new (t->d()) typename ManagedType::Data(arg1, arg2, arg3, arg4, arg5);
- return t;
+ return t.asReturned();
}
bool isGCBlocked() const;
void setGCBlocked(bool blockGC);
void runGC();
+ ExecutionEngine *engine() const;
void setExecutionEngine(ExecutionEngine *engine);
void dumpStats() const;
diff --git a/src/qml/jsruntime/qv4numberobject.cpp b/src/qml/jsruntime/qv4numberobject.cpp
index 227ff14104..44826c94c8 100644
--- a/src/qml/jsruntime/qv4numberobject.cpp
+++ b/src/qml/jsruntime/qv4numberobject.cpp
@@ -32,6 +32,8 @@
****************************************************************************/
#include "qv4numberobject_p.h"
+#include "qv4runtime_p.h"
+
#include <QtCore/qnumeric.h>
#include <QtCore/qmath.h>
#include <QtCore/QDebug>
@@ -99,7 +101,7 @@ inline ReturnedValue thisNumberValue(ExecutionContext *ctx)
return ctx->d()->callData->thisObject.asReturnedValue();
NumberObject *n = ctx->d()->callData->thisObject.asNumberObject();
if (!n)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
return n->value().asReturnedValue();
}
@@ -109,7 +111,7 @@ inline double thisNumber(ExecutionContext *ctx)
return ctx->d()->callData->thisObject.asDouble();
NumberObject *n = ctx->d()->callData->thisObject.asNumberObject();
if (!n)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
return n->value().asDouble();
}
@@ -122,7 +124,7 @@ ReturnedValue NumberPrototype::method_toString(CallContext *ctx)
if (ctx->d()->callData->argc && !ctx->d()->callData->args[0].isUndefined()) {
int radix = ctx->d()->callData->args[0].toInt32();
if (radix < 2 || radix > 36)
- return ctx->throwError(QString::fromLatin1("Number.prototype.toString: %0 is not a valid radix")
+ return ctx->engine()->throwError(QString::fromLatin1("Number.prototype.toString: %0 is not a valid radix")
.arg(radix));
if (std::isnan(num)) {
@@ -195,7 +197,7 @@ ReturnedValue NumberPrototype::method_toFixed(CallContext *ctx)
fdigits = 0;
if (fdigits < 0 || fdigits > 20)
- return ctx->throwRangeError(ctx->d()->callData->thisObject);
+ return ctx->engine()->throwRangeError(ctx->d()->callData->thisObject);
QString str;
if (std::isnan(v))
@@ -222,7 +224,7 @@ ReturnedValue NumberPrototype::method_toExponential(CallContext *ctx)
fdigits = ctx->d()->callData->args[0].toInt32();
if (fdigits < 0 || fdigits > 20) {
ScopedString error(scope, ctx->d()->engine->newString(QStringLiteral("Number.prototype.toExponential: fractionDigits out of range")));
- return ctx->throwRangeError(error);
+ return ctx->engine()->throwRangeError(error);
}
}
@@ -247,7 +249,7 @@ ReturnedValue NumberPrototype::method_toPrecision(CallContext *ctx)
double precision = ctx->d()->callData->args[0].toInt32();
if (precision < 1 || precision > 21) {
ScopedString error(scope, ctx->d()->engine->newString(QStringLiteral("Number.prototype.toPrecision: precision out of range")));
- return ctx->throwRangeError(error);
+ return ctx->engine()->throwRangeError(error);
}
char str[100];
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index 0c61d666ab..576537dcef 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -41,22 +41,9 @@
#include "qv4lookup_p.h"
#include "qv4scopedvalue_p.h"
#include "qv4memberdata_p.h"
+#include "qv4objectiterator_p.h"
-#include <private/qqmljsengine_p.h>
-#include <private/qqmljslexer_p.h>
-#include <private/qqmljsparser_p.h>
-#include <private/qqmljsast_p.h>
-#include <qv4jsir_p.h>
-#include <qv4codegen_p.h>
-#include "private/qlocale_tools_p.h"
-
-#include <QtCore/qmath.h>
-#include <QtCore/QDebug>
-#include <cassert>
-#include <typeinfo>
-#include <iostream>
#include <stdint.h>
-#include "qv4alloca_p.h"
using namespace QV4;
@@ -130,7 +117,7 @@ void Object::putValue(Property *pd, PropertyAttributes attrs, const ValueRef val
reject:
if (engine()->currentContext()->d()->strictMode)
- engine()->currentContext()->throwTypeError();
+ engine()->throwTypeError();
}
void Object::defineDefaultProperty(const QString &name, ValueRef value)
@@ -191,13 +178,13 @@ void Object::defineReadonlyProperty(String *name, ValueRef value)
insertMember(name, value, Attr_ReadOnly);
}
-void Object::markObjects(Managed *that, ExecutionEngine *e)
+void Object::markObjects(HeapObject *that, ExecutionEngine *e)
{
- Object *o = static_cast<Object *>(that);
+ Object::Data *o = static_cast<Object::Data *>(that);
- o->memberData().mark(e);
- if (o->arrayData())
- o->arrayData()->mark(e);
+ o->memberData.mark(e);
+ if (o->arrayData)
+ o->arrayData->mark(e);
}
void Object::ensureMemberIndex(uint idx)
@@ -369,12 +356,12 @@ bool Object::hasOwnProperty(uint index) const
ReturnedValue Object::construct(Managed *m, CallData *)
{
- return m->engine()->currentContext()->throwTypeError();
+ return m->engine()->throwTypeError();
}
ReturnedValue Object::call(Managed *m, CallData *)
{
- return m->engine()->currentContext()->throwTypeError();
+ return m->engine()->throwTypeError();
}
ReturnedValue Object::get(Managed *m, String *name, bool *hasProperty)
@@ -678,7 +665,7 @@ void Object::internalPut(String *name, const ValueRef value)
bool ok;
uint l = value->asArrayLength(&ok);
if (!ok) {
- engine()->currentContext()->throwRangeError(value);
+ engine()->throwRangeError(value);
return;
}
ok = setArrayLength(l);
@@ -727,7 +714,7 @@ void Object::internalPut(String *name, const ValueRef value)
QString message = QStringLiteral("Cannot assign to read-only property \"");
message += name->toQString();
message += QLatin1Char('\"');
- engine()->currentContext()->throwTypeError(message);
+ engine()->throwTypeError(message);
}
}
@@ -796,7 +783,7 @@ void Object::internalPutIndexed(uint index, const ValueRef value)
reject:
if (engine()->currentContext()->d()->strictMode)
- engine()->currentContext()->throwTypeError();
+ engine()->throwTypeError();
}
// Section 8.12.7
@@ -818,7 +805,7 @@ bool Object::internalDeleteProperty(String *name)
return true;
}
if (engine()->currentContext()->d()->strictMode)
- engine()->currentContext()->throwTypeError();
+ engine()->throwTypeError();
return false;
}
@@ -834,7 +821,7 @@ bool Object::internalDeleteIndexedProperty(uint index)
return true;
if (engine()->currentContext()->d()->strictMode)
- engine()->currentContext()->throwTypeError();
+ engine()->throwTypeError();
return false;
}
@@ -866,7 +853,7 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, String *name, const Pr
uint l = p.value.asArrayLength(&ok);
if (!ok) {
ScopedValue v(scope, p.value);
- ctx->throwRangeError(v);
+ ctx->engine()->throwRangeError(v);
return false;
}
succeeded = setArrayLength(l);
@@ -900,7 +887,7 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, String *name, const Pr
return __defineOwnProperty__(ctx, memberIndex, name, p, attrs);
reject:
if (ctx->d()->strictMode)
- ctx->throwTypeError();
+ ctx->engine()->throwTypeError();
return false;
}
@@ -916,7 +903,7 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, uint index, const Prop
return defineOwnProperty2(ctx, index, p, attrs);
reject:
if (ctx->d()->strictMode)
- ctx->throwTypeError();
+ ctx->engine()->throwTypeError();
return false;
}
@@ -952,7 +939,7 @@ bool Object::defineOwnProperty2(ExecutionContext *ctx, uint index, const Propert
return __defineOwnProperty__(ctx, index, 0, p, attrs);
reject:
if (ctx->d()->strictMode)
- ctx->throwTypeError();
+ ctx->engine()->throwTypeError();
return false;
}
@@ -1045,7 +1032,7 @@ bool Object::__defineOwnProperty__(ExecutionContext *ctx, uint index, String *me
return true;
reject:
if (ctx->d()->strictMode)
- ctx->throwTypeError();
+ ctx->engine()->throwTypeError();
return false;
}
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index 4e9d1527c2..f11220f55c 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -30,70 +30,17 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#ifndef QMLJS_OBJECTS_H
-#define QMLJS_OBJECTS_H
-
-#include "qv4global_p.h"
-#include "qv4runtime_p.h"
-#include "qv4engine_p.h"
-#include "qv4context_p.h"
-#include "qv4string_p.h"
+#ifndef QV4_OBJECT_H
+#define QV4_OBJECT_H
+
#include "qv4managed_p.h"
-#include "qv4property_p.h"
-#include "qv4internalclass_p.h"
-#include "qv4arraydata_p.h"
#include "qv4memberdata_p.h"
-
-#include <QtCore/QString>
-#include <QtCore/QHash>
-#include <QtCore/QScopedPointer>
-#include <cstdio>
-#include <cassert>
-
-#ifdef _WIN32_WCE
-#undef assert
-#define assert(x)
-#endif // _WIN32_WCE
+#include "qv4arraydata_p.h"
QT_BEGIN_NAMESPACE
namespace QV4 {
-struct Function;
-struct Lookup;
-struct Object;
-struct ObjectIterator;
-struct BooleanObject;
-struct NumberObject;
-struct StringObject;
-struct ArrayObject;
-struct DateObject;
-struct FunctionObject;
-struct RegExpObject;
-struct ErrorObject;
-struct ArgumentsObject;
-struct ExecutionContext;
-struct CallContext;
-struct ExecutionEngine;
-class MemoryManager;
-
-struct ObjectPrototype;
-struct StringPrototype;
-struct NumberPrototype;
-struct BooleanPrototype;
-struct ArrayPrototype;
-struct FunctionPrototype;
-struct DatePrototype;
-struct RegExpPrototype;
-struct ErrorPrototype;
-struct EvalErrorPrototype;
-struct RangeErrorPrototype;
-struct ReferenceErrorPrototype;
-struct SyntaxErrorPrototype;
-struct TypeErrorPrototype;
-struct URIErrorPrototype;
-
-
struct Q_QML_EXPORT Object: Managed {
struct Data : Managed::Data {
Data(ExecutionEngine *engine)
@@ -277,7 +224,7 @@ public:
inline ReturnedValue call(CallData *d)
{ return vtable()->call(this, d); }
protected:
- static void markObjects(Managed *that, ExecutionEngine *e);
+ static void markObjects(HeapObject *that, ExecutionEngine *e);
static ReturnedValue construct(Managed *m, CallData *);
static ReturnedValue call(Managed *m, CallData *);
static ReturnedValue get(Managed *m, String *name, bool *hasProperty);
diff --git a/src/qml/jsruntime/qv4objectiterator.cpp b/src/qml/jsruntime/qv4objectiterator.cpp
index f9038472df..e0f7087437 100644
--- a/src/qml/jsruntime/qv4objectiterator.cpp
+++ b/src/qml/jsruntime/qv4objectiterator.cpp
@@ -68,15 +68,15 @@ ObjectIterator::ObjectIterator(Value *scratch1, Value *scratch2, uint flags)
, memberIndex(0)
, flags(flags)
{
- object->o = (Object*)0;
- current->o = (Object*)0;
+ object->m = 0;
+ current->m = 0;
// Caller needs to call init!
}
void ObjectIterator::init(Object *o)
{
- object->o = o;
- current->o = o;
+ object->m = o ? &o->data : 0;
+ current->m = o ? &o->data : 0;
#if QT_POINTER_SIZE == 4
object->tag = QV4::Value::Managed_Type;
@@ -125,10 +125,11 @@ void ObjectIterator::next(String *&name, uint *index, Property *pd, PropertyAttr
return;
}
- if (flags & WithProtoChain)
- current->o = current->objectValue()->prototype();
- else
- current->o = (Object *)0;
+ if (flags & WithProtoChain) {
+ Object *proto = current->objectValue()->prototype();
+ current->m = proto ? &proto->data : 0;
+ } else
+ current->m = (HeapObject *)0;
arrayIndex = 0;
memberIndex = 0;
@@ -209,10 +210,10 @@ ReturnedValue ObjectIterator::nextPropertyNameAsString()
DEFINE_OBJECT_VTABLE(ForEachIteratorObject);
-void ForEachIteratorObject::markObjects(Managed *that, ExecutionEngine *e)
+void ForEachIteratorObject::markObjects(HeapObject *that, ExecutionEngine *e)
{
- ForEachIteratorObject *o = static_cast<ForEachIteratorObject *>(that);
- o->d()->workArea[0].mark(e);
- o->d()->workArea[1].mark(e);
+ ForEachIteratorObject::Data *o = static_cast<ForEachIteratorObject::Data *>(that);
+ o->workArea[0].mark(e);
+ o->workArea[1].mark(e);
Object::markObjects(that, e);
}
diff --git a/src/qml/jsruntime/qv4objectiterator_p.h b/src/qml/jsruntime/qv4objectiterator_p.h
index 3ed73b5c08..10f75a1e0d 100644
--- a/src/qml/jsruntime/qv4objectiterator_p.h
+++ b/src/qml/jsruntime/qv4objectiterator_p.h
@@ -34,24 +34,12 @@
#define QV4OBJECTITERATOR_H
#include "qv4global_p.h"
-#include "qv4property_p.h"
-#include "qv4scopedvalue_p.h"
#include "qv4object_p.h"
QT_BEGIN_NAMESPACE
namespace QV4 {
-struct SparseArrayNode;
-struct Object;
-struct ArrayObject;
-struct PropertyAttributes;
-struct ExecutionContext;
-struct Property;
-struct String;
-struct InternalClass;
-struct ForEachIteratorObject;
-
struct Q_QML_EXPORT ObjectIterator
{
enum Flags {
@@ -81,8 +69,8 @@ private:
struct ForEachIteratorObject: Object {
struct Data : Object::Data {
- Data(ExecutionContext *ctx, Object *o)
- : Object::Data(ctx->engine())
+ Data(ExecutionEngine *engine, Object *o)
+ : Object::Data(engine)
, it(workArea, workArea + 1, o, ObjectIterator::EnumerableOnly|ObjectIterator::WithProtoChain) {
setVTable(staticVTable());
}
@@ -95,7 +83,7 @@ struct ForEachIteratorObject: Object {
ReturnedValue nextPropertyName() { return d()->it.nextPropertyNameAsString(); }
protected:
- static void markObjects(Managed *that, ExecutionEngine *e);
+ static void markObjects(HeapObject *that, ExecutionEngine *e);
};
diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp
index 9cbf4b204e..5a4fe253e2 100644
--- a/src/qml/jsruntime/qv4objectproto.cpp
+++ b/src/qml/jsruntime/qv4objectproto.cpp
@@ -36,30 +36,13 @@
#include "qv4argumentsobject_p.h"
#include "qv4mm_p.h"
#include "qv4scopedvalue_p.h"
+#include "qv4runtime_p.h"
+#include "qv4objectiterator_p.h"
+
#include <QtCore/qnumeric.h>
#include <QtCore/qmath.h>
#include <QtCore/QDateTime>
#include <QtCore/QStringList>
-#include <QtCore/QDebug>
-#include <cassert>
-
-#include <private/qqmljsengine_p.h>
-#include <private/qqmljslexer_p.h>
-#include <private/qqmljsparser_p.h>
-#include <private/qqmljsast_p.h>
-#include <qv4jsir_p.h>
-#include <qv4codegen_p.h>
-
-#ifndef Q_OS_WIN
-# include <time.h>
-# ifndef Q_OS_VXWORKS
-# include <sys/time.h>
-# else
-# include "qplatformdefs.h"
-# endif
-#else
-# include <windows.h>
-#endif
using namespace QV4;
@@ -135,7 +118,7 @@ ReturnedValue ObjectPrototype::method_getPrototypeOf(CallContext *ctx)
Scope scope(ctx);
Scoped<Object> o(scope, ctx->argument(0));
if (!o)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
Scoped<Object> p(scope, o->prototype());
return !!p ? p->asReturnedValue() : Encode::null();
@@ -146,7 +129,7 @@ ReturnedValue ObjectPrototype::method_getOwnPropertyDescriptor(CallContext *ctx)
Scope scope(ctx);
Scoped<Object> O(scope, ctx->argument(0));
if (!O)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
if (ArgumentsObject::isNonStrictArgumentsObject(O.getPointer()))
Scoped<ArgumentsObject>(scope, O)->fullyCreate();
@@ -165,7 +148,7 @@ ReturnedValue ObjectPrototype::method_getOwnPropertyNames(CallContext *context)
Scope scope(context);
ScopedObject O(scope, context->argument(0));
if (!O)
- return context->throwTypeError();
+ return context->engine()->throwTypeError();
ScopedArrayObject array(scope, getOwnPropertyNames(context->d()->engine, context->d()->callData->args[0]));
return array.asReturnedValue();
@@ -176,7 +159,7 @@ ReturnedValue ObjectPrototype::method_create(CallContext *ctx)
Scope scope(ctx);
ScopedValue O(scope, ctx->argument(0));
if (!O->isObject() && !O->isNull())
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
Scoped<Object> newObject(scope, ctx->d()->engine->newObject());
newObject->setPrototype(O->asObject());
@@ -194,7 +177,7 @@ ReturnedValue ObjectPrototype::method_defineProperty(CallContext *ctx)
Scope scope(ctx);
Scoped<Object> O(scope, ctx->argument(0));
if (!O)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
Scoped<String> name(scope, ctx->argument(1), Scoped<String>::Convert);
if (scope.engine->hasException)
@@ -208,7 +191,7 @@ ReturnedValue ObjectPrototype::method_defineProperty(CallContext *ctx)
return Encode::undefined();
if (!O->__defineOwnProperty__(ctx, name.getPointer(), pd, attrs))
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
return O.asReturnedValue();
}
@@ -218,7 +201,7 @@ ReturnedValue ObjectPrototype::method_defineProperties(CallContext *ctx)
Scope scope(ctx);
Scoped<Object> O(scope, ctx->argument(0));
if (!O)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
Scoped<Object> o(scope, ctx->argument(1), Scoped<Object>::Convert);
if (scope.engine->hasException)
@@ -248,7 +231,7 @@ ReturnedValue ObjectPrototype::method_defineProperties(CallContext *ctx)
else
ok = O->__defineOwnProperty__(ctx, index, n, nattrs);
if (!ok)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
}
return O.asReturnedValue();
@@ -259,7 +242,7 @@ ReturnedValue ObjectPrototype::method_seal(CallContext *ctx)
Scope scope(ctx);
Scoped<Object> o(scope, ctx->argument(0));
if (!o)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
o->setExtensible(false);
@@ -281,7 +264,7 @@ ReturnedValue ObjectPrototype::method_freeze(CallContext *ctx)
Scope scope(ctx);
Scoped<Object> o(scope, ctx->argument(0));
if (!o)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
if (ArgumentsObject::isNonStrictArgumentsObject(o.getPointer()))
Scoped<ArgumentsObject>(scope, o)->fullyCreate();
@@ -307,7 +290,7 @@ ReturnedValue ObjectPrototype::method_preventExtensions(CallContext *ctx)
Scope scope(ctx);
Scoped<Object> o(scope, ctx->argument(0));
if (!o)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
o->setExtensible(false);
return o.asReturnedValue();
@@ -318,7 +301,7 @@ ReturnedValue ObjectPrototype::method_isSealed(CallContext *ctx)
Scope scope(ctx);
Scoped<Object> o(scope, ctx->argument(0));
if (!o)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
if (o->isExtensible())
return Encode(false);
@@ -347,7 +330,7 @@ ReturnedValue ObjectPrototype::method_isFrozen(CallContext *ctx)
Scope scope(ctx);
Scoped<Object> o(scope, ctx->argument(0));
if (!o)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
if (o->isExtensible())
return Encode(false);
@@ -376,7 +359,7 @@ ReturnedValue ObjectPrototype::method_isExtensible(CallContext *ctx)
Scope scope(ctx);
Scoped<Object> o(scope, ctx->argument(0));
if (!o)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
return Encode((bool)o->isExtensible());
}
@@ -386,7 +369,7 @@ ReturnedValue ObjectPrototype::method_keys(CallContext *ctx)
Scope scope(ctx);
Scoped<Object> o(scope, ctx->argument(0));
if (!o)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
Scoped<ArrayObject> a(scope, ctx->d()->engine->newArrayObject());
@@ -424,7 +407,7 @@ ReturnedValue ObjectPrototype::method_toLocaleString(CallContext *ctx)
return Encode::undefined();
Scoped<FunctionObject> f(scope, o->get(ctx->d()->engine->id_toString));
if (!f)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
ScopedCallData callData(scope, 0);
callData->thisObject = o;
return f->call(callData);
@@ -491,12 +474,12 @@ ReturnedValue ObjectPrototype::method_propertyIsEnumerable(CallContext *ctx)
ReturnedValue ObjectPrototype::method_defineGetter(CallContext *ctx)
{
if (ctx->d()->callData->argc < 2)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
Scope scope(ctx);
Scoped<FunctionObject> f(scope, ctx->argument(1));
if (!f)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
Scoped<String> prop(scope, ctx->argument(0), Scoped<String>::Convert);
if (scope.engine->hasException)
@@ -519,12 +502,12 @@ ReturnedValue ObjectPrototype::method_defineGetter(CallContext *ctx)
ReturnedValue ObjectPrototype::method_defineSetter(CallContext *ctx)
{
if (ctx->d()->callData->argc < 2)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
Scope scope(ctx);
Scoped<FunctionObject> f(scope, ctx->argument(1));
if (!f)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
Scoped<String> prop(scope, ctx->argument(0), Scoped<String>::Convert);
if (scope.engine->hasException)
@@ -549,7 +532,7 @@ ReturnedValue ObjectPrototype::method_get_proto(CallContext *ctx)
Scope scope(ctx);
ScopedObject o(scope, ctx->d()->callData->thisObject.asObject());
if (!o)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
return o->prototype()->asReturnedValue();
}
@@ -559,7 +542,7 @@ ReturnedValue ObjectPrototype::method_set_proto(CallContext *ctx)
Scope scope(ctx);
Scoped<Object> o(scope, ctx->d()->callData->thisObject);
if (!o || !ctx->d()->callData->argc)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
if (ctx->d()->callData->args[0].isNull()) {
o->setPrototype(0);
@@ -576,7 +559,7 @@ ReturnedValue ObjectPrototype::method_set_proto(CallContext *ctx)
}
}
if (!ok)
- return ctx->throwTypeError(QStringLiteral("Cyclic __proto__ value"));
+ return ctx->engine()->throwTypeError(QStringLiteral("Cyclic __proto__ value"));
return Encode::undefined();
}
@@ -585,7 +568,7 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, const ValueRef
Scope scope(ctx);
ScopedObject o(scope, v);
if (!o) {
- ctx->throwTypeError();
+ ctx->engine()->throwTypeError();
return;
}
@@ -606,7 +589,7 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, const ValueRef
if (f || get->isUndefined()) {
desc->value = get;
} else {
- ctx->throwTypeError();
+ ctx->engine()->throwTypeError();
return;
}
attrs->setType(PropertyAttributes::Accessor);
@@ -618,7 +601,7 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, const ValueRef
if (f || set->isUndefined()) {
desc->set = set;
} else {
- ctx->throwTypeError();
+ ctx->engine()->throwTypeError();
return;
}
attrs->setType(PropertyAttributes::Accessor);
@@ -626,7 +609,7 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, const ValueRef
if (o->hasProperty(ctx->d()->engine->id_writable)) {
if (attrs->isAccessor()) {
- ctx->throwTypeError();
+ ctx->engine()->throwTypeError();
return;
}
attrs->setWritable((tmp = o->get(ctx->d()->engine->id_writable))->toBoolean());
@@ -636,7 +619,7 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, const ValueRef
if (o->hasProperty(ctx->d()->engine->id_value)) {
if (attrs->isAccessor()) {
- ctx->throwTypeError();
+ ctx->engine()->throwTypeError();
return;
}
desc->value = o->get(ctx->d()->engine->id_value);
diff --git a/src/qml/jsruntime/qv4property_p.h b/src/qml/jsruntime/qv4property_p.h
index f9b3159033..601e3446f4 100644
--- a/src/qml/jsruntime/qv4property_p.h
+++ b/src/qml/jsruntime/qv4property_p.h
@@ -34,7 +34,7 @@
#define QV4PROPERTYDESCRIPTOR_H
#include "qv4global_p.h"
-#include "qv4value_inl_p.h"
+#include "qv4value_p.h"
#include "qv4internalclass_p.h"
QT_BEGIN_NAMESPACE
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index f2c30e618f..cf59fe027c 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -443,7 +443,7 @@ void QObjectWrapper::setProperty(QObject *object, ExecutionContext *ctx, QQmlPro
if (!property->isWritable() && !property->isQList()) {
QString error = QLatin1String("Cannot assign to read-only property \"") +
property->name(object) + QLatin1Char('\"');
- ctx->throwTypeError(error);
+ ctx->engine()->throwTypeError(error);
return;
}
@@ -459,7 +459,7 @@ void QObjectWrapper::setProperty(QObject *object, ExecutionContext *ctx, QQmlPro
error += QLatin1String("[unknown property type]");
else
error += QLatin1String(QMetaType::typeName(property->propType));
- ctx->throwError(error);
+ ctx->engine()->throwError(error);
return;
}
} else {
@@ -511,7 +511,7 @@ void QObjectWrapper::setProperty(QObject *object, ExecutionContext *ctx, QQmlPro
error += QLatin1String("[unknown property type]");
else
error += QLatin1String(QMetaType::typeName(property->propType));
- ctx->throwError(error);
+ ctx->engine()->throwError(error);
return;
} else if (value->asFunctionObject()) {
// this is handled by the binding creation above
@@ -560,7 +560,7 @@ void QObjectWrapper::setProperty(QObject *object, ExecutionContext *ctx, QQmlPro
QLatin1String(valueType) +
QLatin1String(" to ") +
QLatin1String(targetTypeName);
- ctx->throwError(error);
+ ctx->engine()->throwError(error);
return;
}
}
@@ -693,7 +693,7 @@ void QObjectWrapper::put(Managed *m, String *name, const ValueRef value)
if (ddata && ddata->context) {
QString error = QLatin1String("Cannot assign to non-existent property \"") +
name->toQString() + QLatin1Char('\"');
- v4->currentContext()->throwError(error);
+ v4->throwError(error);
} else {
QV4::Object::put(m, name, value);
}
@@ -985,11 +985,11 @@ static void markChildQObjectsRecursively(QObject *parent, QV4::ExecutionEngine *
}
}
-void QObjectWrapper::markObjects(Managed *that, QV4::ExecutionEngine *e)
+void QObjectWrapper::markObjects(HeapObject *that, QV4::ExecutionEngine *e)
{
- QObjectWrapper *This = static_cast<QObjectWrapper*>(that);
+ QObjectWrapper::Data *This = static_cast<QObjectWrapper::Data *>(that);
- if (QObject *o = This->d()->object.data()) {
+ if (QObject *o = This->object.data()) {
QQmlVMEMetaObject *vme = QQmlVMEMetaObject::get(o);
if (vme)
vme->mark(e);
@@ -1374,7 +1374,7 @@ static QV4::ReturnedValue CallPrecise(QObject *object, const QQmlPropertyData &d
if (returnType == QMetaType::UnknownType) {
QString typeName = QString::fromLatin1(unknownTypeError);
QString error = QString::fromLatin1("Unknown method return type: %1").arg(typeName);
- return QV8Engine::getV4(engine)->currentContext()->throwError(error);
+ return QV8Engine::getV4(engine)->throwError(error);
}
if (data.hasArguments()) {
@@ -1388,12 +1388,12 @@ static QV4::ReturnedValue CallPrecise(QObject *object, const QQmlPropertyData &d
if (!args) {
QString typeName = QString::fromLatin1(unknownTypeError);
QString error = QString::fromLatin1("Unknown method parameter type: %1").arg(typeName);
- return QV8Engine::getV4(engine)->currentContext()->throwError(error);
+ return QV8Engine::getV4(engine)->throwError(error);
}
if (args[0] > callArgs->argc) {
QString error = QLatin1String("Insufficient arguments");
- return QV8Engine::getV4(engine)->currentContext()->throwError(error);
+ return QV8Engine::getV4(engine)->throwError(error);
}
return CallMethod(object, data.coreIndex, returnType, args[0], args + 1, engine, callArgs);
@@ -1492,7 +1492,7 @@ static QV4::ReturnedValue CallOverloaded(QObject *object, const QQmlPropertyData
candidate = RelatedMethod(object, candidate, dummy);
}
- return QV8Engine::getV4(engine)->currentContext()->throwError(error);
+ return QV8Engine::getV4(engine)->throwError(error);
}
}
@@ -1793,7 +1793,7 @@ QV4::ReturnedValue QObjectMethod::method_destroy(QV4::ExecutionContext *ctx, con
if (!d()->object)
return Encode::undefined();
if (QQmlData::keepAliveDuringGarbageCollection(d()->object))
- return ctx->throwError(QStringLiteral("Invalid attempt to destroy() an indestructible object"));
+ return ctx->engine()->throwError(QStringLiteral("Invalid attempt to destroy() an indestructible object"));
int delay = 0;
if (argc > 0)
diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h
index 1a31b5af4b..6458f03037 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper_p.h
+++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h
@@ -108,7 +108,7 @@ private:
static void put(Managed *m, String *name, const ValueRef value);
static PropertyAttributes query(const Managed *, String *name);
static void advanceIterator(Managed *m, ObjectIterator *it, String *&name, uint *index, Property *p, PropertyAttributes *attributes);
- static void markObjects(Managed *that, QV4::ExecutionEngine *e);
+ static void markObjects(HeapObject *that, QV4::ExecutionEngine *e);
static void destroy(Managed *that);
static ReturnedValue method_connect(CallContext *ctx);
diff --git a/src/qml/jsruntime/qv4regexp.cpp b/src/qml/jsruntime/qv4regexp.cpp
index e84c96f417..659221b0d9 100644
--- a/src/qml/jsruntime/qv4regexp.cpp
+++ b/src/qml/jsruntime/qv4regexp.cpp
@@ -63,17 +63,18 @@ uint RegExp::match(const QString &string, int start, uint *matchOffsets)
return JSC::Yarr::interpret(byteCode().get(), s.characters16(), string.length(), start, matchOffsets);
}
-RegExp* RegExp::create(ExecutionEngine* engine, const QString& pattern, bool ignoreCase, bool multiline)
+Returned<RegExp> *RegExp::create(ExecutionEngine* engine, const QString& pattern, bool ignoreCase, bool multiline)
{
RegExpCacheKey key(pattern, ignoreCase, multiline);
RegExpCache *cache = engine->regExpCache;
if (cache) {
if (RegExp *result = cache->value(key))
- return result;
+ return Returned<RegExp>::create(result);
}
- RegExp *result = engine->memoryManager->alloc<RegExp>(engine, pattern, ignoreCase, multiline);
+ Scope scope(engine);
+ Scoped<RegExp> result(scope, engine->memoryManager->alloc<RegExp>(engine, pattern, ignoreCase, multiline));
if (!cache)
cache = engine->regExpCache = new RegExpCache;
@@ -81,7 +82,7 @@ RegExp* RegExp::create(ExecutionEngine* engine, const QString& pattern, bool ign
result->d()->cache = cache;
cache->insert(key, result);
- return result;
+ return result.asReturned();
}
RegExp::Data::Data(ExecutionEngine* engine, const QString &pattern, bool ignoreCase, bool multiline)
@@ -118,7 +119,7 @@ void RegExp::destroy(Managed *that)
static_cast<RegExp*>(that)->d()->~Data();
}
-void RegExp::markObjects(Managed *that, ExecutionEngine *e)
+void RegExp::markObjects(HeapObject *that, ExecutionEngine *e)
{
Q_UNUSED(that);
Q_UNUSED(e);
diff --git a/src/qml/jsruntime/qv4regexp_p.h b/src/qml/jsruntime/qv4regexp_p.h
index e2f43bf7d7..7aad1a32f2 100644
--- a/src/qml/jsruntime/qv4regexp_p.h
+++ b/src/qml/jsruntime/qv4regexp_p.h
@@ -85,7 +85,7 @@ struct RegExp : public Managed
bool ignoreCase() const { return d()->ignoreCase; }
bool multiLine() const { return d()->multiLine; }
- static RegExp* create(ExecutionEngine* engine, const QString& pattern, bool ignoreCase = false, bool multiline = false);
+ static Returned<RegExp> *create(ExecutionEngine* engine, const QString& pattern, bool ignoreCase = false, bool multiline = false);
bool isValid() const { return d()->byteCode.get(); }
@@ -94,7 +94,7 @@ struct RegExp : public Managed
int captureCount() const { return subPatternCount() + 1; }
static void destroy(Managed *that);
- static void markObjects(Managed *that, QV4::ExecutionEngine *e);
+ static void markObjects(HeapObject *that, QV4::ExecutionEngine *e);
friend class RegExpCache;
};
diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp
index c48175247e..23b46c8492 100644
--- a/src/qml/jsruntime/qv4regexpobject.cpp
+++ b/src/qml/jsruntime/qv4regexpobject.cpp
@@ -71,7 +71,7 @@ RegExpObject::Data::Data(InternalClass *ic)
Scope scope(ic->engine);
Scoped<RegExpObject> o(scope, this);
- o->d()->value = reinterpret_cast<RegExp *>(RegExp::create(ic->engine, QString(), false, false));
+ o->d()->value = RegExp::create(ic->engine, QString(), false, false)->getPointer();
o->d()->global = false;
o->init(ic->engine);
}
@@ -139,7 +139,7 @@ RegExpObject::Data::Data(ExecutionEngine *engine, const QRegExp &re)
Scope scope(engine);
Scoped<RegExpObject> o(scope, this);
- o->d()->value = reinterpret_cast<RegExp *>(RegExp::create(engine, pattern, re.caseSensitivity() == Qt::CaseInsensitive, false));
+ o->d()->value = RegExp::create(engine, pattern, re.caseSensitivity() == Qt::CaseInsensitive, false)->getPointer();
o->init(engine);
}
@@ -170,11 +170,11 @@ void RegExpObject::init(ExecutionEngine *engine)
}
-void RegExpObject::markObjects(Managed *that, ExecutionEngine *e)
+void RegExpObject::markObjects(HeapObject *that, ExecutionEngine *e)
{
- RegExpObject *re = static_cast<RegExpObject*>(that);
- if (re->value())
- re->value()->mark(e);
+ RegExpObject::Data *re = static_cast<RegExpObject::Data *>(that);
+ if (re->value)
+ re->value->mark(e);
Object::markObjects(that, e);
}
@@ -254,7 +254,7 @@ ReturnedValue RegExpCtor::construct(Managed *m, CallData *callData)
Scoped<RegExpObject> re(scope, r);
if (re) {
if (!f->isUndefined())
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
return Encode(ctx->d()->engine->newRegExpObject(re->value(), re->global()));
}
@@ -281,14 +281,14 @@ ReturnedValue RegExpCtor::construct(Managed *m, CallData *callData)
} else if (str.at(i) == QLatin1Char('m') && !multiLine) {
multiLine = true;
} else {
- return ctx->throwSyntaxError(QStringLiteral("Invalid flags supplied to RegExp constructor"));
+ return ctx->engine()->throwSyntaxError(QStringLiteral("Invalid flags supplied to RegExp constructor"));
}
}
}
- RegExp *regexp = reinterpret_cast<RegExp *>(RegExp::create(ctx->d()->engine, pattern, ignoreCase, multiLine));
+ Scoped<RegExp> regexp(scope, RegExp::create(ctx->d()->engine, pattern, ignoreCase, multiLine));
if (!regexp->isValid())
- return ctx->throwSyntaxError(QStringLiteral("Invalid regular expression"));
+ return ctx->engine()->throwSyntaxError(QStringLiteral("Invalid regular expression"));
return Encode(ctx->d()->engine->newRegExpObject(regexp, global));
}
@@ -303,11 +303,11 @@ ReturnedValue RegExpCtor::call(Managed *that, CallData *callData)
return construct(that, callData);
}
-void RegExpCtor::markObjects(Managed *that, ExecutionEngine *e)
+void RegExpCtor::markObjects(HeapObject *that, ExecutionEngine *e)
{
- RegExpCtor *This = static_cast<RegExpCtor*>(that);
- This->lastMatch().mark(e);
- This->lastInput().mark(e);
+ RegExpCtor::Data *This = static_cast<RegExpCtor::Data *>(that);
+ This->lastMatch.mark(e);
+ This->lastInput.mark(e);
FunctionObject::markObjects(that, e);
}
@@ -353,7 +353,7 @@ ReturnedValue RegExpPrototype::method_exec(CallContext *ctx)
Scope scope(ctx);
Scoped<RegExpObject> r(scope, ctx->d()->callData->thisObject.as<RegExpObject>());
if (!r)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
ScopedValue arg(scope, ctx->argument(0));
arg = RuntimeHelpers::toString(ctx, arg);
@@ -417,7 +417,7 @@ ReturnedValue RegExpPrototype::method_toString(CallContext *ctx)
Scope scope(ctx);
Scoped<RegExpObject> r(scope, ctx->d()->callData->thisObject.as<RegExpObject>());
if (!r)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
return ctx->d()->engine->newString(r->toString())->asReturnedValue();
}
@@ -427,7 +427,7 @@ ReturnedValue RegExpPrototype::method_compile(CallContext *ctx)
Scope scope(ctx);
Scoped<RegExpObject> r(scope, ctx->d()->callData->thisObject.as<RegExpObject>());
if (!r)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
ScopedCallData callData(scope, ctx->d()->callData->argc);
memcpy(callData->args, ctx->d()->callData->args, ctx->d()->callData->argc*sizeof(Value));
diff --git a/src/qml/jsruntime/qv4regexpobject_p.h b/src/qml/jsruntime/qv4regexpobject_p.h
index e2f8049157..cf59ca12c0 100644
--- a/src/qml/jsruntime/qv4regexpobject_p.h
+++ b/src/qml/jsruntime/qv4regexpobject_p.h
@@ -91,7 +91,7 @@ struct RegExpObject: Object {
uint flags() const;
protected:
- static void markObjects(Managed *that, ExecutionEngine *e);
+ static void markObjects(HeapObject *that, ExecutionEngine *e);
};
struct RegExpCtor: FunctionObject
@@ -113,7 +113,7 @@ struct RegExpCtor: FunctionObject
static ReturnedValue construct(Managed *m, CallData *callData);
static ReturnedValue call(Managed *that, CallData *callData);
- static void markObjects(Managed *that, ExecutionEngine *e);
+ static void markObjects(HeapObject *that, ExecutionEngine *e);
};
struct RegExpPrototype: RegExpObject
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index f72f25bd58..b817bc594b 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -35,11 +35,11 @@
#include "qv4runtime_p.h"
#ifndef V4_BOOTSTRAP
#include "qv4object_p.h"
-#include "qv4jsir_p.h"
#include "qv4objectproto_p.h"
#include "qv4globalobject_p.h"
#include "qv4stringobject_p.h"
#include "qv4argumentsobject_p.h"
+#include "qv4objectiterator_p.h"
#include "qv4lookup_p.h"
#include "qv4function_p.h"
#include "private/qlocale_tools_p.h"
@@ -300,7 +300,7 @@ QV4::ReturnedValue Runtime::instanceof(ExecutionContext *ctx, const ValueRef lef
FunctionObject *f = right->asFunctionObject();
if (!f)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
if (f->subtype() == FunctionObject::BoundFunction)
f = static_cast<BoundFunction *>(f)->target();
@@ -311,7 +311,7 @@ QV4::ReturnedValue Runtime::instanceof(ExecutionContext *ctx, const ValueRef lef
Object *o = QV4::Value::fromReturnedValue(f->protoProperty()).asObject();
if (!o)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
while (v) {
v = v->prototype();
@@ -328,7 +328,7 @@ QV4::ReturnedValue Runtime::instanceof(ExecutionContext *ctx, const ValueRef lef
QV4::ReturnedValue Runtime::in(ExecutionContext *ctx, const ValueRef left, const ValueRef right)
{
if (!right->isObject())
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
Scope scope(ctx);
ScopedString s(scope, left->toString(ctx));
if (scope.hasException())
@@ -406,7 +406,7 @@ ReturnedValue RuntimeHelpers::objectDefaultValue(Object *object, int typeHint)
return r->asReturnedValue();
}
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
}
@@ -417,7 +417,7 @@ Returned<Object> *RuntimeHelpers::convertToObject(ExecutionContext *ctx, const V
switch (value->type()) {
case Value::Undefined_Type:
case Value::Null_Type:
- ctx->throwTypeError();
+ ctx->engine()->throwTypeError();
return 0;
case Value::Boolean_Type:
return ctx->engine()->newBooleanObject(value);
@@ -571,7 +571,7 @@ ReturnedValue Runtime::getElement(ExecutionContext *ctx, const ValueRef object,
if (object->isNullOrUndefined()) {
QString message = QStringLiteral("Cannot read property '%1' of %2").arg(index->toQStringNoThrow()).arg(object->toQStringNoThrow());
- return ctx->throwTypeError(message);
+ return ctx->engine()->throwTypeError(message);
}
o = RuntimeHelpers::convertToObject(ctx, object);
@@ -625,8 +625,7 @@ ReturnedValue Runtime::foreachIterator(ExecutionContext *ctx, const ValueRef in)
Scoped<Object> o(scope, (Object *)0);
if (!in->isNullOrUndefined())
o = in->toObject(ctx);
- Scoped<Object> it(scope, ctx->engine()->newForEachIteratorObject(ctx, o));
- return it.asReturnedValue();
+ return ctx->engine()->newForEachIteratorObject(o)->asReturnedValue();
}
ReturnedValue Runtime::foreachNextPropertyName(const ValueRef foreach_iterator)
@@ -655,7 +654,7 @@ ReturnedValue Runtime::getProperty(ExecutionContext *ctx, const ValueRef object,
if (object->isNullOrUndefined()) {
QString message = QStringLiteral("Cannot read property '%1' of %2").arg(name->toQString()).arg(object->toQStringNoThrow());
- return ctx->throwTypeError(message);
+ return ctx->engine()->throwTypeError(message);
}
o = RuntimeHelpers::convertToObject(ctx, object);
@@ -721,7 +720,7 @@ Bool RuntimeHelpers::strictEqual(const ValueRef x, const ValueRef y)
if (x->isNumber())
return y->isNumber() && x->asDouble() == y->asDouble();
if (x->isManaged())
- return y->isManaged() && x->managed()->isEqualTo(y->managed());
+ return y->isManaged() && x->cast<Managed>()->isEqualTo(y->cast<Managed>());
return false;
}
@@ -858,6 +857,25 @@ QV4::Bool Runtime::compareLessEqual(const QV4::ValueRef l, const QV4::ValueRef r
}
#ifndef V4_BOOTSTRAP
+Bool Runtime::compareInstanceof(ExecutionContext *ctx, const ValueRef left, const ValueRef right)
+{
+ TRACE2(left, right);
+
+ Scope scope(ctx);
+ ScopedValue v(scope, Runtime::instanceof(ctx, left, right));
+ return v->booleanValue();
+}
+
+uint Runtime::compareIn(ExecutionContext *ctx, const ValueRef left, const ValueRef right)
+{
+ TRACE2(left, right);
+
+ Scope scope(ctx);
+ ScopedValue v(scope, Runtime::in(ctx, left, right));
+ return v->booleanValue();
+}
+
+
ReturnedValue Runtime::callGlobalLookup(ExecutionContext *context, uint index, CallData *callData)
{
Scope scope(context);
@@ -866,7 +884,7 @@ ReturnedValue Runtime::callGlobalLookup(ExecutionContext *context, uint index, C
Lookup *l = context->d()->lookups + index;
Scoped<FunctionObject> o(scope, l->globalGetter(l, context));
if (!o)
- return context->throwTypeError();
+ return context->engine()->throwTypeError();
if (o.getPointer() == scope.engine->evalFunction && l->name->equals(scope.engine->id_eval))
return static_cast<EvalFunction *>(o.getPointer())->evalCall(callData, true);
@@ -881,7 +899,9 @@ ReturnedValue Runtime::callActivationProperty(ExecutionContext *context, String
Scope scope(context);
ScopedObject base(scope);
- ScopedValue func(scope, context->getPropertyAndBase(name, base.ptr->o));
+ Object *baseObj = 0;
+ ScopedValue func(scope, context->getPropertyAndBase(name, baseObj));
+ base.ptr->m = baseObj ? &baseObj->data : 0;
if (scope.engine->hasException)
return Encode::undefined();
@@ -894,7 +914,7 @@ ReturnedValue Runtime::callActivationProperty(ExecutionContext *context, String
if (base)
objectAsString = ScopedValue(scope, base.asReturnedValue())->toQStringNoThrow();
QString msg = QStringLiteral("Property '%1' of object %2 is not a function").arg(name->toQString()).arg(objectAsString);
- return context->throwTypeError(msg);
+ return context->engine()->throwTypeError(msg);
}
if (o == scope.engine->evalFunction && name->equals(scope.engine->id_eval)) {
@@ -912,7 +932,7 @@ ReturnedValue Runtime::callProperty(ExecutionContext *context, String *name, Cal
Q_ASSERT(!callData->thisObject.isEmpty());
if (callData->thisObject.isNullOrUndefined()) {
QString message = QStringLiteral("Cannot call method '%1' of %2").arg(name->toQString()).arg(callData->thisObject.toQStringNoThrow());
- return context->throwTypeError(message);
+ return context->engine()->throwTypeError(message);
}
baseObject = RuntimeHelpers::convertToObject(context, ValueRef(&callData->thisObject));
@@ -924,7 +944,7 @@ ReturnedValue Runtime::callProperty(ExecutionContext *context, String *name, Cal
Scoped<FunctionObject> o(scope, baseObject->get(name));
if (!o) {
QString error = QStringLiteral("Property '%1' of object %2 is not a function").arg(name->toQString(), callData->thisObject.toQStringNoThrow());
- return context->throwTypeError(error);
+ return context->engine()->throwTypeError(error);
}
return o->call(callData);
@@ -936,7 +956,7 @@ ReturnedValue Runtime::callPropertyLookup(ExecutionContext *context, uint index,
Value v;
v = l->getter(l, callData->thisObject);
if (!v.isObject())
- return context->throwTypeError();
+ return context->engine()->throwTypeError();
return v.objectValue()->call(callData);
}
@@ -953,7 +973,7 @@ ReturnedValue Runtime::callElement(ExecutionContext *context, const ValueRef ind
ScopedObject o(scope, baseObject->get(s.getPointer()));
if (!o)
- return context->throwTypeError();
+ return context->engine()->throwTypeError();
return o->call(callData);
}
@@ -961,7 +981,7 @@ ReturnedValue Runtime::callElement(ExecutionContext *context, const ValueRef ind
ReturnedValue Runtime::callValue(ExecutionContext *context, const ValueRef func, CallData *callData)
{
if (!func->isObject())
- return context->throwTypeError();
+ return context->engine()->throwTypeError();
return func->objectValue()->call(callData);
}
@@ -975,7 +995,7 @@ ReturnedValue Runtime::constructGlobalLookup(ExecutionContext *context, uint ind
Lookup *l = context->d()->lookups + index;
Scoped<Object> f(scope, l->globalGetter(l, context));
if (!f)
- return context->throwTypeError();
+ return context->engine()->throwTypeError();
return f->construct(callData);
}
@@ -990,7 +1010,7 @@ ReturnedValue Runtime::constructActivationProperty(ExecutionContext *context, St
Object *f = func->asObject();
if (!f)
- return context->throwTypeError();
+ return context->engine()->throwTypeError();
return f->construct(callData);
}
@@ -999,7 +1019,7 @@ ReturnedValue Runtime::constructValue(ExecutionContext *context, const ValueRef
{
Object *f = func->asObject();
if (!f)
- return context->throwTypeError();
+ return context->engine()->throwTypeError();
return f->construct(callData);
}
@@ -1013,7 +1033,7 @@ ReturnedValue Runtime::constructProperty(ExecutionContext *context, String *name
Scoped<Object> f(scope, thisObject->get(name));
if (!f)
- return context->throwTypeError();
+ return context->engine()->throwTypeError();
return f->construct(callData);
}
@@ -1024,7 +1044,7 @@ ReturnedValue Runtime::constructPropertyLookup(ExecutionContext *context, uint i
Value v;
v = l->getter(l, callData->thisObject);
if (!v.isObject())
- return context->throwTypeError();
+ return context->engine()->throwTypeError();
return v.objectValue()->construct(callData);
}
@@ -1033,7 +1053,7 @@ ReturnedValue Runtime::constructPropertyLookup(ExecutionContext *context, uint i
void Runtime::throwException(ExecutionContext *context, const ValueRef value)
{
if (!value->isEmpty())
- context->throwError(value);
+ context->engine()->throwError(value);
}
ReturnedValue Runtime::typeofValue(ExecutionContext *ctx, const ValueRef value)
@@ -1099,7 +1119,7 @@ ExecutionContext *Runtime::pushWithScope(const ValueRef o, ExecutionContext *ctx
{
Scope scope(ctx);
ScopedObject obj(scope, o->toObject(ctx));
- return reinterpret_cast<ExecutionContext *>(ctx->newWithContext(obj));
+ return ctx->newWithContext(obj)->getPointer();
}
ReturnedValue Runtime::unwindException(ExecutionContext *ctx)
@@ -1113,7 +1133,7 @@ ExecutionContext *Runtime::pushCatchScope(ExecutionContext *ctx, String *excepti
{
Scope scope(ctx);
ScopedValue v(scope, ctx->engine()->catchException(ctx, 0));
- return reinterpret_cast<ExecutionContext *>(ctx->newCatchContext(exceptionVarName, v));
+ return ctx->newCatchContext(exceptionVarName, v)->getPointer();
}
ExecutionContext *Runtime::popScope(ExecutionContext *ctx)
@@ -1300,7 +1320,7 @@ ReturnedValue Runtime::getQmlQObjectProperty(ExecutionContext *ctx, const ValueR
Scope scope(ctx);
QV4::Scoped<QObjectWrapper> wrapper(scope, object);
if (!wrapper) {
- ctx->throwTypeError(QStringLiteral("Cannot read property of null"));
+ ctx->engine()->throwTypeError(QStringLiteral("Cannot read property of null"));
return Encode::undefined();
}
return QV4::QObjectWrapper::getProperty(wrapper->object(), ctx, propertyIndex, captureRequired);
@@ -1323,7 +1343,7 @@ ReturnedValue Runtime::getQmlSingletonQObjectProperty(ExecutionContext *ctx, con
Scope scope(ctx);
QV4::Scoped<QmlTypeWrapper> wrapper(scope, object);
if (!wrapper) {
- ctx->throwTypeError(QStringLiteral("Cannot read property of null"));
+ scope.engine->throwTypeError(QStringLiteral("Cannot read property of null"));
return Encode::undefined();
}
return QV4::QObjectWrapper::getProperty(wrapper->singletonObject(), ctx, propertyIndex, captureRequired);
@@ -1334,7 +1354,7 @@ void Runtime::setQmlQObjectProperty(ExecutionContext *ctx, const ValueRef object
Scope scope(ctx);
QV4::Scoped<QObjectWrapper> wrapper(scope, object);
if (!wrapper) {
- ctx->throwTypeError(QStringLiteral("Cannot write property of null"));
+ ctx->engine()->throwTypeError(QStringLiteral("Cannot write property of null"));
return;
}
wrapper->setProperty(ctx, propertyIndex, value);
diff --git a/src/qml/jsruntime/qv4runtime_p.h b/src/qml/jsruntime/qv4runtime_p.h
index 6042420291..f69ea1620c 100644
--- a/src/qml/jsruntime/qv4runtime_p.h
+++ b/src/qml/jsruntime/qv4runtime_p.h
@@ -35,20 +35,11 @@
#include "qv4global_p.h"
#include "qv4value_inl_p.h"
-#include "qv4math_p.h"
-#include "qv4scopedvalue_p.h"
#include "qv4context_p.h"
+#include "qv4math_p.h"
-#include <QtCore/QString>
#include <QtCore/qnumeric.h>
-#include <QtCore/QDebug>
-#include <QtCore/qurl.h>
-#include <cmath>
-#include <cassert>
-#include <limits>
-
-//#include <wtf/MathExtras.h>
QT_BEGIN_NAMESPACE
@@ -470,7 +461,7 @@ inline Bool Runtime::compareEqual(const ValueRef left, const ValueRef right)
if (!left->isManaged())
return false;
if (left->isString() == right->isString())
- return left->managed()->isEqualTo(right->managed());
+ return left->cast<Managed>()->isEqualTo(right->cast<Managed>());
}
return RuntimeHelpers::equalHelper(left, right);
@@ -529,27 +520,6 @@ inline Bool Runtime::compareStrictNotEqual(const ValueRef left, const ValueRef r
return ! RuntimeHelpers::strictEqual(left, right);
}
-#ifndef V4_BOOTSTRAP
-inline Bool Runtime::compareInstanceof(ExecutionContext *ctx, const ValueRef left, const ValueRef right)
-{
- TRACE2(left, right);
-
- Scope scope(ctx);
- ScopedValue v(scope, Runtime::instanceof(ctx, left, right));
- return v->booleanValue();
-}
-
-inline uint Runtime::compareIn(ExecutionContext *ctx, const ValueRef left, const ValueRef right)
-{
- TRACE2(left, right);
-
- Scope scope(ctx);
- ScopedValue v(scope, Runtime::in(ctx, left, right));
- return v->booleanValue();
-}
-
-#endif // V4_BOOTSTRAP
-
inline Bool Runtime::toBoolean(const ValueRef value)
{
return value->toBoolean();
diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h
index b1b4d5da8d..90a3bf1602 100644
--- a/src/qml/jsruntime/qv4scopedvalue_p.h
+++ b/src/qml/jsruntime/qv4scopedvalue_p.h
@@ -36,6 +36,7 @@
#include "qv4engine_p.h"
#include "qv4value_p.h"
#include "qv4persistent_p.h"
+#include "qv4property_p.h"
QT_BEGIN_NAMESPACE
@@ -112,7 +113,7 @@ struct ScopedValue
ScopedValue(const Scope &scope, HeapObject *o)
{
ptr = scope.engine->jsStackTop++;
- ptr->m = reinterpret_cast<Managed *>(o);
+ ptr->m = o;
#if QT_POINTER_SIZE == 4
ptr->tag = QV4::Value::Managed_Type;
#endif
@@ -155,7 +156,7 @@ struct ScopedValue
}
ScopedValue &operator=(HeapObject *o) {
- ptr->m = reinterpret_cast<Managed *>(o);
+ ptr->m = o;
#if QT_POINTER_SIZE == 4
ptr->tag = QV4::Value::Managed_Type;
#endif
@@ -204,7 +205,7 @@ struct Scoped
inline void setPointer(Managed *p) {
#if QT_POINTER_SIZE == 8
- ptr->val = (quint64)p;
+ ptr->val = (quint64)(p ? &p->data : 0);
#else
*ptr = p ? QV4::Value::fromManaged(p) : QV4::Primitive::undefinedValue();
#endif
@@ -230,7 +231,7 @@ struct Scoped
Scoped(const Scope &scope, HeapObject *o)
{
Value v;
- v.m = reinterpret_cast<Managed *>(o);
+ v.m = o;
#if QT_POINTER_SIZE == 4
v.tag = QV4::Value::Managed_Type;
#endif
@@ -317,7 +318,7 @@ struct Scoped
Scoped<T> &operator=(HeapObject *o) {
Value v;
- v.m = reinterpret_cast<Managed *>(o);
+ v.m = o;
#if QT_POINTER_SIZE == 4
v.tag = QV4::Value::Managed_Type;
#endif
@@ -357,14 +358,14 @@ struct Scoped
}
T *operator->() {
- return static_cast<T *>(ptr->managed());
+ return ptr->cast<T>();
}
bool operator!() const {
- return !ptr->managed();
+ return !ptr->m;
}
operator void *() const {
- return ptr->managed();
+ return ptr->m;
}
T *getPointer() {
@@ -379,6 +380,8 @@ struct Scoped
#endif
}
+ Returned<T> *asReturned() const { return Returned<T>::create(static_cast<typename T::Data*>(ptr->heapObject())); }
+
Value *ptr;
};
@@ -478,7 +481,7 @@ inline Returned<T> *Value::as()
template<typename T>
inline TypedValue<T> &TypedValue<T>::operator =(T *t)
{
- m = t;
+ m = t ? &t->data : 0;
#if QT_POINTER_SIZE == 4
tag = Managed_Type;
#endif
@@ -488,7 +491,7 @@ inline TypedValue<T> &TypedValue<T>::operator =(T *t)
template<typename T>
inline TypedValue<T> &TypedValue<T>::operator =(const Scoped<T> &v)
{
- m = v.ptr->managed();
+ m = v.ptr->m;
#if QT_POINTER_SIZE == 4
tag = Managed_Type;
#endif
@@ -519,7 +522,7 @@ inline TypedValue<T> &TypedValue<T>::operator=(const TypedValue<T> &t)
template<typename T>
inline Returned<T> * TypedValue<T>::ret() const
{
- return Returned<T>::create(static_cast<T *>(managed()));
+ return Returned<T>::create(static_cast<typename T::Data *>(heapObject()));
}
inline Primitive::operator ValueRef()
diff --git a/src/qml/jsruntime/qv4script.cpp b/src/qml/jsruntime/qv4script.cpp
index fa4b4b1894..5c0c3f32ff 100644
--- a/src/qml/jsruntime/qv4script.cpp
+++ b/src/qml/jsruntime/qv4script.cpp
@@ -70,7 +70,7 @@ QmlBindingWrapper::Data::Data(ExecutionContext *scope, Function *f, Object *qml)
o->defineReadonlyProperty(scope->d()->engine->id_length, Primitive::fromInt32(1));
- o->d()->qmlContext = reinterpret_cast<CallContext *>(s.engine->currentContext()->newQmlContext(o, qml));
+ o->d()->qmlContext = s.engine->currentContext()->newQmlContext(o, qml)->getPointer();
s.engine->popContext();
}
@@ -88,7 +88,7 @@ QmlBindingWrapper::Data::Data(ExecutionContext *scope, Object *qml)
o->defineReadonlyProperty(scope->d()->engine->id_length, Primitive::fromInt32(1));
- o->d()->qmlContext = reinterpret_cast<CallContext *>(s.engine->currentContext()->newQmlContext(o, qml));
+ o->d()->qmlContext = s.engine->currentContext()->newQmlContext(o, qml)->getPointer();
s.engine->popContext();
}
@@ -111,14 +111,14 @@ ReturnedValue QmlBindingWrapper::call(Managed *that, CallData *)
return result.asReturnedValue();
}
-void QmlBindingWrapper::markObjects(Managed *m, ExecutionEngine *e)
+void QmlBindingWrapper::markObjects(HeapObject *m, ExecutionEngine *e)
{
- QmlBindingWrapper *wrapper = static_cast<QmlBindingWrapper*>(m);
- if (wrapper->d()->qml)
- wrapper->d()->qml->mark(e);
+ QmlBindingWrapper::Data *wrapper = static_cast<QmlBindingWrapper::Data *>(m);
+ if (wrapper->qml)
+ wrapper->qml->mark(e);
FunctionObject::markObjects(m, e);
- if (wrapper->d()->qmlContext)
- wrapper->d()->qmlContext->mark(e);
+ if (wrapper->qmlContext)
+ wrapper->qmlContext->mark(e);
}
static ReturnedValue signalParameterGetter(QV4::CallContext *ctx, uint parameterIndex)
@@ -224,7 +224,7 @@ void Script::parse()
foreach (const QQmlJS::DiagnosticMessage &m, parser.diagnosticMessages()) {
if (m.isError()) {
- scope->throwSyntaxError(m.message, sourceFile, m.loc.startLine, m.loc.startColumn);
+ scope->engine()->throwSyntaxError(m.message, sourceFile, m.loc.startLine, m.loc.startColumn);
return;
} else {
qWarning() << sourceFile << ':' << m.loc.startLine << ':' << m.loc.startColumn
@@ -268,7 +268,7 @@ void Script::parse()
if (!vmFunction) {
// ### FIX file/line number
Scoped<Object> error(valueScope, v4->newSyntaxErrorObject(QStringLiteral("Syntax error")));
- v4->currentContext()->throwError(error);
+ v4->throwError(error);
}
}
diff --git a/src/qml/jsruntime/qv4script_p.h b/src/qml/jsruntime/qv4script_p.h
index ed93ce49ae..f12d5ad6fc 100644
--- a/src/qml/jsruntime/qv4script_p.h
+++ b/src/qml/jsruntime/qv4script_p.h
@@ -82,7 +82,7 @@ struct Q_QML_EXPORT QmlBindingWrapper : FunctionObject {
V4_OBJECT(FunctionObject)
static ReturnedValue call(Managed *that, CallData *);
- static void markObjects(Managed *m, ExecutionEngine *e);
+ static void markObjects(HeapObject *m, ExecutionEngine *e);
CallContext *context() const { return d()->qmlContext; }
diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp
index 83bfb65658..c63e634025 100644
--- a/src/qml/jsruntime/qv4sequenceobject.cpp
+++ b/src/qml/jsruntime/qv4sequenceobject.cpp
@@ -39,7 +39,8 @@
#include <private/qv4arrayobject_p.h>
#include <private/qqmlengine_p.h>
#include <private/qv4scopedvalue_p.h>
-#include <private/qv4internalclass_p.h>
+#include "qv4runtime_p.h"
+#include "qv4objectiterator_p.h"
#include <algorithm>
@@ -401,7 +402,7 @@ public:
QV4::Scope scope(ctx);
QV4::Scoped<QQmlSequence<Container> > This(scope, ctx->d()->callData->thisObject.as<QQmlSequence<Container> >());
if (!This)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
if (This->d()->isReference) {
if (!This->d()->object)
@@ -416,7 +417,7 @@ public:
QV4::Scope scope(ctx);
QV4::Scoped<QQmlSequence<Container> > This(scope, ctx->d()->callData->thisObject.as<QQmlSequence<Container> >());
if (!This)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
quint32 newLength = ctx->d()->callData->args[0].toUInt32();
/* Qt containers have int (rather than uint) allowable indexes. */
@@ -544,7 +545,7 @@ QV4::ReturnedValue SequencePrototype::method_sort(QV4::CallContext *ctx)
QV4::Scope scope(ctx);
QV4::ScopedObject o(scope, ctx->d()->callData->thisObject);
if (!o || !o->isListType())
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
if (ctx->d()->callData->argc >= 2)
return o.asReturnedValue();
diff --git a/src/qml/jsruntime/qv4sequenceobject_p.h b/src/qml/jsruntime/qv4sequenceobject_p.h
index be348e524c..c0848ec0ba 100644
--- a/src/qml/jsruntime/qv4sequenceobject_p.h
+++ b/src/qml/jsruntime/qv4sequenceobject_p.h
@@ -50,6 +50,7 @@
#include "qv4value_inl_p.h"
#include "qv4object_p.h"
+#include "qv4context_p.h"
QT_BEGIN_NAMESPACE
diff --git a/src/qml/jsruntime/qv4string.cpp b/src/qml/jsruntime/qv4string.cpp
index bd8a5ffccb..4ae10f6506 100644
--- a/src/qml/jsruntime/qv4string.cpp
+++ b/src/qml/jsruntime/qv4string.cpp
@@ -122,12 +122,12 @@ void String::destroy(Managed *that)
static_cast<String*>(that)->d()->~Data();
}
-void String::markObjects(Managed *that, ExecutionEngine *e)
+void String::markObjects(HeapObject *that, ExecutionEngine *e)
{
- String *s = static_cast<String *>(that);
- if (s->d()->largestSubLength) {
- s->d()->left->mark(e);
- s->d()->right->mark(e);
+ String::Data *s = static_cast<String::Data *>(that);
+ if (s->largestSubLength) {
+ s->left->mark(e);
+ s->right->mark(e);
}
}
diff --git a/src/qml/jsruntime/qv4string_p.h b/src/qml/jsruntime/qv4string_p.h
index ce0e1f9d73..1e53132fe3 100644
--- a/src/qml/jsruntime/qv4string_p.h
+++ b/src/qml/jsruntime/qv4string_p.h
@@ -154,7 +154,7 @@ struct Q_QML_PRIVATE_EXPORT String : public Managed {
protected:
static void destroy(Managed *);
- static void markObjects(Managed *that, ExecutionEngine *e);
+ static void markObjects(HeapObject *that, ExecutionEngine *e);
static ReturnedValue get(Managed *m, String *name, bool *hasProperty);
static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty);
static void put(Managed *m, String *name, const ValueRef value);
@@ -171,20 +171,6 @@ public:
static uint toArrayIndex(const QString &str);
};
-#ifndef V4_BOOTSTRAP
-template<>
-inline String *value_cast(const Value &v) {
- return v.asString();
-}
-
-template<>
-inline ReturnedValue value_convert<String>(ExecutionEngine *e, const Value &v)
-{
- return v.toString(e)->asReturnedValue();
-}
-
-#endif
-
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp
index 397a6efdf8..19ef7892ad 100644
--- a/src/qml/jsruntime/qv4stringobject.cpp
+++ b/src/qml/jsruntime/qv4stringobject.cpp
@@ -109,13 +109,13 @@ bool StringObject::deleteIndexedProperty(Managed *m, uint index)
Scope scope(v4);
Scoped<StringObject> o(scope, m->asStringObject());
if (!o) {
- v4->currentContext()->throwTypeError();
+ v4->throwTypeError();
return false;
}
if (index < static_cast<uint>(o->d()->value.stringValue()->toQString().length())) {
if (v4->currentContext()->d()->strictMode)
- v4->currentContext()->throwTypeError();
+ v4->throwTypeError();
return false;
}
return true;
@@ -149,11 +149,11 @@ void StringObject::advanceIterator(Managed *m, ObjectIterator *it, String *&name
return Object::advanceIterator(m, it, name, index, p, attrs);
}
-void StringObject::markObjects(Managed *that, ExecutionEngine *e)
+void StringObject::markObjects(HeapObject *that, ExecutionEngine *e)
{
- StringObject *o = static_cast<StringObject *>(that);
- o->d()->value.stringValue()->mark(e);
- o->d()->tmpProperty.value.mark(e);
+ StringObject::Data *o = static_cast<StringObject::Data *>(that);
+ o->value.stringValue()->mark(e);
+ o->tmpProperty.value.mark(e);
Object::markObjects(that, e);
}
@@ -230,7 +230,7 @@ static QString getThisString(ExecutionContext *ctx)
if (StringObject *thisString = t->asStringObject())
return thisString->d()->value.stringValue()->toQString();
if (t->isUndefined() || t->isNull()) {
- ctx->throwTypeError();
+ ctx->engine()->throwTypeError();
return QString();
}
return t->toQString();
@@ -243,7 +243,7 @@ ReturnedValue StringPrototype::method_toString(CallContext *context)
StringObject *o = context->d()->callData->thisObject.asStringObject();
if (!o)
- return context->throwTypeError();
+ return context->engine()->throwTypeError();
return o->d()->value.asReturnedValue();
}
@@ -365,7 +365,7 @@ ReturnedValue StringPrototype::method_localeCompare(CallContext *context)
ReturnedValue StringPrototype::method_match(CallContext *context)
{
if (context->d()->callData->thisObject.isUndefined() || context->d()->callData->thisObject.isNull())
- return context->throwTypeError();
+ return context->engine()->throwTypeError();
Scope scope(context);
ScopedString s(scope, context->d()->callData->thisObject.toString(context));
@@ -380,7 +380,7 @@ ReturnedValue StringPrototype::method_match(CallContext *context)
if (!rx)
// ### CHECK
- return context->throwTypeError();
+ return context->engine()->throwTypeError();
bool global = rx->global();
diff --git a/src/qml/jsruntime/qv4stringobject_p.h b/src/qml/jsruntime/qv4stringobject_p.h
index 5d3c0c9ccb..28e944c791 100644
--- a/src/qml/jsruntime/qv4stringobject_p.h
+++ b/src/qml/jsruntime/qv4stringobject_p.h
@@ -59,7 +59,7 @@ struct StringObject: Object {
protected:
static void advanceIterator(Managed *m, ObjectIterator *it, String *&name, uint *index, Property *p, PropertyAttributes *attrs);
- static void markObjects(Managed *that, ExecutionEngine *e);
+ static void markObjects(HeapObject *that, ExecutionEngine *e);
};
struct StringCtor: FunctionObject
diff --git a/src/qml/jsruntime/qv4typedarray.cpp b/src/qml/jsruntime/qv4typedarray.cpp
new file mode 100644
index 0000000000..72823efa12
--- /dev/null
+++ b/src/qml/jsruntime/qv4typedarray.cpp
@@ -0,0 +1,572 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "qv4typedarray_p.h"
+#include "qv4arraybuffer_p.h"
+
+using namespace QV4;
+
+DEFINE_OBJECT_VTABLE(TypedArrayCtor);
+DEFINE_OBJECT_VTABLE(TypedArrayPrototype);
+DEFINE_OBJECT_VTABLE(TypedArray);
+
+Q_STATIC_ASSERT((int)ExecutionEngine::NTypedArrayTypes == (int)TypedArray::NTypes);
+
+ReturnedValue Int8ArrayRead(const char *data, int index)
+{
+ return Encode((int)(signed char)data[index]);
+}
+
+void Int8ArrayWrite(ExecutionEngine *e, char *data, int index, ValueRef value)
+{
+ signed char v = (signed char)value->toUInt32();
+ if (e->hasException)
+ return;
+ data[index] = v;
+}
+
+ReturnedValue UInt8ArrayRead(const char *data, int index)
+{
+ return Encode((int)(unsigned char)data[index]);
+}
+
+void UInt8ArrayWrite(ExecutionEngine *e, char *data, int index, ValueRef value)
+{
+ unsigned char v = (unsigned char)value->toUInt32();
+ if (e->hasException)
+ return;
+ data[index] = v;
+}
+
+void UInt8ClampedArrayWrite(ExecutionEngine *e, char *data, int index, ValueRef value)
+{
+ if (value->isInteger()) {
+ data[index] = (char)(unsigned char)qBound(0, value->integerValue(), 255);
+ return;
+ }
+ double d = value->toNumber();
+ if (e->hasException)
+ return;
+ // ### is there a way to optimise this?
+ if (d <= 0 || std::isnan(d)) {
+ data[index] = 0;
+ return;
+ }
+ if (d >= 255) {
+ data[index] = 255;
+ return;
+ }
+ double f = floor(d);
+ if (f + 0.5 < d) {
+ data[index] = (unsigned char)(f + 1);
+ return;
+ }
+ if (d < f + 0.5) {
+ data[index] = (unsigned char)(f);
+ return;
+ }
+ if (int(f) % 2) {
+ // odd number
+ data[index] = (unsigned char)(f + 1);
+ return;
+ }
+ data[index] = (unsigned char)(f);
+}
+
+ReturnedValue Int16ArrayRead(const char *data, int index)
+{
+ return Encode((int)*(short *)(data + index));
+}
+
+void Int16ArrayWrite(ExecutionEngine *e, char *data, int index, ValueRef value)
+{
+ short v = (short)value->toInt32();
+ if (e->hasException)
+ return;
+ *(short *)(data + index) = v;
+}
+
+ReturnedValue UInt16ArrayRead(const char *data, int index)
+{
+ return Encode((int)*(unsigned short *)(data + index));
+}
+
+void UInt16ArrayWrite(ExecutionEngine *e, char *data, int index, ValueRef value)
+{
+ unsigned short v = (unsigned short)value->toInt32();
+ if (e->hasException)
+ return;
+ *(unsigned short *)(data + index) = v;
+}
+
+ReturnedValue Int32ArrayRead(const char *data, int index)
+{
+ return Encode(*(int *)(data + index));
+}
+
+void Int32ArrayWrite(ExecutionEngine *e, char *data, int index, ValueRef value)
+{
+ int v = (int)value->toInt32();
+ if (e->hasException)
+ return;
+ *(int *)(data + index) = v;
+}
+
+ReturnedValue UInt32ArrayRead(const char *data, int index)
+{
+ return Encode(*(unsigned int *)(data + index));
+}
+
+void UInt32ArrayWrite(ExecutionEngine *e, char *data, int index, ValueRef value)
+{
+ unsigned int v = (unsigned int)value->toUInt32();
+ if (e->hasException)
+ return;
+ *(unsigned int *)(data + index) = v;
+}
+
+ReturnedValue Float32ArrayRead(const char *data, int index)
+{
+ return Encode(*(float *)(data + index));
+}
+
+void Float32ArrayWrite(ExecutionEngine *e, char *data, int index, ValueRef value)
+{
+ float v = value->toNumber();
+ if (e->hasException)
+ return;
+ *(float *)(data + index) = v;
+}
+
+ReturnedValue Float64ArrayRead(const char *data, int index)
+{
+ return Encode(*(double *)(data + index));
+}
+
+void Float64ArrayWrite(ExecutionEngine *e, char *data, int index, ValueRef value)
+{
+ double v = value->toNumber();
+ if (e->hasException)
+ return;
+ *(double *)(data + index) = v;
+}
+
+const TypedArrayOperations operations[TypedArray::NTypes] = {
+ { 1, "Int8Array", Int8ArrayRead, Int8ArrayWrite },
+ { 1, "Uint8Array", UInt8ArrayRead, UInt8ArrayWrite },
+ { 1, "Uint8ClampedArray", UInt8ArrayRead, UInt8ClampedArrayWrite },
+ { 2, "Int16Array", Int16ArrayRead, Int16ArrayWrite },
+ { 2, "Uint16Array", UInt16ArrayRead, UInt16ArrayWrite },
+ { 4, "Int32Array", Int32ArrayRead, Int32ArrayWrite },
+ { 4, "Uint32Array", UInt32ArrayRead, UInt32ArrayWrite },
+ { 4, "Float32Array", Float32ArrayRead, Float32ArrayWrite },
+ { 8, "Float64Array", Float64ArrayRead, Float64ArrayWrite },
+};
+
+
+TypedArrayCtor::Data::Data(ExecutionContext *scope, TypedArray::Type t)
+ : FunctionObject::Data(scope, QLatin1String(operations[t].name))
+ , type(t)
+{
+ setVTable(staticVTable());
+}
+
+ReturnedValue TypedArrayCtor::construct(Managed *m, CallData *callData)
+{
+ Scope scope(m->engine());
+ Scoped<TypedArrayCtor> that(scope, static_cast<TypedArrayCtor *>(m));
+
+ if (!callData->argc || !callData->args[0].isObject()) {
+ // ECMA 6 22.2.1.1
+ double l = callData->argc ? callData->args[0].toNumber() : 0;
+ if (scope.engine->hasException)
+ return Encode::undefined();
+ uint len = (uint)l;
+ if (l != len)
+ scope.engine->throwRangeError(QStringLiteral("Non integer length for typed array."));
+ uint byteLength = len * operations[that->d()->type].bytesPerElement;
+ Scoped<ArrayBuffer> buffer(scope, scope.engine->memoryManager->alloc<ArrayBuffer>(scope.engine, byteLength));
+ if (scope.engine->hasException)
+ return Encode::undefined();
+
+ Scoped<TypedArray > array(scope, scope.engine->memoryManager->alloc<TypedArray>(scope.engine, that->d()->type));
+ array->d()->buffer = buffer;
+ array->d()->byteLength = byteLength;
+ array->d()->byteOffset = 0;
+
+ return array.asReturnedValue();
+ }
+ Scoped<TypedArray> typedArray(scope, callData->argument(0));
+ if (!!typedArray) {
+ // ECMA 6 22.2.1.2
+ Scoped<ArrayBuffer> buffer(scope, typedArray->d()->buffer);
+ uint srcElementSize = typedArray->d()->type->bytesPerElement;
+ uint destElementSize = operations[that->d()->type].bytesPerElement;
+ uint byteLength = typedArray->d()->byteLength;
+ uint destByteLength = byteLength*destElementSize/srcElementSize;
+
+ Scoped<ArrayBuffer> newBuffer(scope, scope.engine->memoryManager->alloc<ArrayBuffer>(scope.engine, destByteLength));
+ if (scope.engine->hasException)
+ return Encode::undefined();
+
+ Scoped<TypedArray > array(scope, scope.engine->memoryManager->alloc<TypedArray>(scope.engine, that->d()->type));
+ array->d()->buffer = newBuffer;
+ array->d()->byteLength = destByteLength;
+ array->d()->byteOffset = 0;
+
+ const char *src = buffer->d()->data->data() + typedArray->d()->byteOffset;
+ char *dest = newBuffer->d()->data->data();
+
+ // check if src and new type have the same size. In that case we can simply memcpy the data
+ if (srcElementSize == destElementSize) {
+ memcpy(dest, src, byteLength);
+ } else {
+ // not same size, we need to loop
+ uint l = typedArray->length();
+ TypedArrayRead read = typedArray->d()->type->read;
+ TypedArrayWrite write =array->d()->type->write;
+ for (uint i = 0; i < l; ++i) {
+ Primitive val;
+ val.val = read(src, i*srcElementSize);
+ write(scope.engine, dest, i*destElementSize, val);
+ }
+ }
+
+ return array.asReturnedValue();
+ }
+ Scoped<ArrayBuffer> buffer(scope, callData->argument(0));
+ if (!!buffer) {
+ // ECMA 6 22.2.1.4
+
+ double dbyteOffset = callData->argc > 1 ? callData->args[1].toInteger() : 0;
+ uint byteOffset = (uint)dbyteOffset;
+ uint elementSize = operations[that->d()->type].bytesPerElement;
+ if (dbyteOffset < 0 || (byteOffset % elementSize) || dbyteOffset > buffer->byteLength())
+ return scope.engine->throwRangeError(QStringLiteral("new TypedArray: invalid byteOffset"));
+
+ uint byteLength;
+ if (callData->argc < 3 || callData->args[2].isUndefined()) {
+ byteLength = buffer->byteLength() - byteOffset;
+ if (buffer->byteLength() < byteOffset || byteLength % elementSize)
+ return scope.engine->throwRangeError(QStringLiteral("new TypedArray: invalid length"));
+ } else {
+ double l = qBound(0., callData->args[2].toInteger(), (double)UINT_MAX);
+ if (scope.engine->hasException)
+ return Encode::undefined();
+ l *= elementSize;
+ if (buffer->byteLength() - byteOffset < l)
+ return scope.engine->throwRangeError(QStringLiteral("new TypedArray: invalid length"));
+ byteLength = (uint)l;
+ }
+
+ Scoped<TypedArray > array(scope, scope.engine->memoryManager->alloc<TypedArray>(scope.engine, that->d()->type));
+ array->d()->buffer = buffer;
+ array->d()->byteLength = byteLength;
+ array->d()->byteOffset = byteOffset;
+ return array.asReturnedValue();
+ }
+
+ // ECMA 6 22.2.1.3
+
+ ScopedObject o(scope, callData->argument(0));
+ uint l = (uint) qBound(0., ScopedValue(scope, o->get(scope.engine->id_length))->toInteger(), (double)UINT_MAX);
+ if (scope.engine->hasException)
+ return scope.engine->throwTypeError();
+
+ uint elementSize = operations[that->d()->type].bytesPerElement;
+ Scoped<ArrayBuffer> newBuffer(scope, scope.engine->memoryManager->alloc<ArrayBuffer>(scope.engine, l * elementSize));
+ if (scope.engine->hasException)
+ return Encode::undefined();
+
+ Scoped<TypedArray > array(scope, scope.engine->memoryManager->alloc<TypedArray>(scope.engine, that->d()->type));
+ array->d()->buffer = newBuffer;
+ array->d()->byteLength = l * elementSize;
+ array->d()->byteOffset = 0;
+
+ uint idx = 0;
+ char *b = newBuffer->d()->data->data();
+ ScopedValue val(scope);
+ while (idx < l) {
+ val = o->getIndexed(idx);
+ array->d()->type->write(scope.engine, b, 0, val);
+ if (scope.engine->hasException)
+ return Encode::undefined();
+ ++idx;
+ b += elementSize;
+ }
+
+
+ return array.asReturnedValue();
+}
+
+ReturnedValue TypedArrayCtor::call(Managed *that, CallData *callData)
+{
+ return construct(that, callData);
+}
+
+TypedArray::Data::Data(ExecutionEngine *e, Type t)
+ : Object::Data(e->typedArrayClasses[t]),
+ type(operations + t)
+{
+}
+
+void TypedArray::markObjects(HeapObject *that, ExecutionEngine *e)
+{
+ static_cast<TypedArray::Data *>(that)->buffer->mark(e);
+ Object::markObjects(that, e);
+}
+
+ReturnedValue TypedArray::getIndexed(Managed *m, uint index, bool *hasProperty)
+{
+ Scope scope(m->engine());
+ Scoped<TypedArray> a(scope, static_cast<TypedArray *>(m));
+
+ uint bytesPerElement = a->d()->type->bytesPerElement;
+ uint byteOffset = a->d()->byteOffset + index * bytesPerElement;
+ if (byteOffset + bytesPerElement > (uint)a->d()->buffer->byteLength()) {
+ if (hasProperty)
+ *hasProperty = false;
+ return Encode::undefined();
+ }
+ if (hasProperty)
+ *hasProperty = true;
+ return a->d()->type->read(a->d()->buffer->d()->data->data(), byteOffset);
+}
+
+void TypedArray::putIndexed(Managed *m, uint index, const ValueRef value)
+{
+ if (m->engine()->hasException)
+ return;
+
+ Scope scope(m->engine());
+ Scoped<TypedArray> a(scope, static_cast<TypedArray *>(m));
+
+ uint bytesPerElement = a->d()->type->bytesPerElement;
+ uint byteOffset = a->d()->byteOffset + index * bytesPerElement;
+ if (byteOffset + bytesPerElement > (uint)a->d()->buffer->byteLength())
+ goto reject;
+
+ a->d()->type->write(scope.engine, a->d()->buffer->d()->data->data(), byteOffset, value);
+ return;
+
+reject:
+ if (scope.engine->currentContext()->d()->strictMode)
+ scope.engine->throwTypeError();
+}
+
+void TypedArrayPrototype::init(ExecutionEngine *engine, TypedArrayCtor *ctor)
+{
+ Scope scope(engine);
+ ScopedObject o(scope);
+ ctor->defineReadonlyProperty(engine->id_length, Primitive::fromInt32(3));
+ ctor->defineReadonlyProperty(engine->id_prototype, (o = this));
+ ctor->defineReadonlyProperty(QStringLiteral("BYTES_PER_ELEMENT"), Primitive::fromInt32(operations[ctor->d()->type].bytesPerElement));
+ defineDefaultProperty(engine->id_constructor, (o = ctor));
+ defineAccessorProperty(QStringLiteral("buffer"), method_get_buffer, 0);
+ defineAccessorProperty(QStringLiteral("byteLength"), method_get_byteLength, 0);
+ defineAccessorProperty(QStringLiteral("byteOffset"), method_get_byteOffset, 0);
+ defineAccessorProperty(QStringLiteral("length"), method_get_length, 0);
+ defineReadonlyProperty(QStringLiteral("BYTES_PER_ELEMENT"), Primitive::fromInt32(operations[ctor->d()->type].bytesPerElement));
+
+ defineDefaultProperty(QStringLiteral("set"), method_set, 1);
+ defineDefaultProperty(QStringLiteral("subarray"), method_subarray, 0);
+}
+
+ReturnedValue TypedArrayPrototype::method_get_buffer(CallContext *ctx)
+{
+ Scope scope(ctx);
+ Scoped<TypedArray> v(scope, ctx->d()->callData->thisObject);
+ if (!v)
+ return scope.engine->throwTypeError();
+
+ return Encode(v->d()->buffer->asReturnedValue());
+}
+
+ReturnedValue TypedArrayPrototype::method_get_byteLength(CallContext *ctx)
+{
+ Scope scope(ctx);
+ Scoped<TypedArray> v(scope, ctx->d()->callData->thisObject);
+ if (!v)
+ return scope.engine->throwTypeError();
+
+ return Encode(v->d()->byteLength);
+}
+
+ReturnedValue TypedArrayPrototype::method_get_byteOffset(CallContext *ctx)
+{
+ Scope scope(ctx);
+ Scoped<TypedArray> v(scope, ctx->d()->callData->thisObject);
+ if (!v)
+ return scope.engine->throwTypeError();
+
+ return Encode(v->d()->byteOffset);
+}
+
+ReturnedValue TypedArrayPrototype::method_get_length(CallContext *ctx)
+{
+ Scope scope(ctx);
+ Scoped<TypedArray> v(scope, ctx->d()->callData->thisObject);
+ if (!v)
+ return scope.engine->throwTypeError();
+
+ return Encode(v->d()->byteLength/v->d()->type->bytesPerElement);
+}
+
+ReturnedValue TypedArrayPrototype::method_set(CallContext *ctx)
+{
+ Scope scope(ctx);
+ Scoped<TypedArray> a(scope, ctx->d()->callData->thisObject);
+ if (!a)
+ return scope.engine->throwTypeError();
+ Scoped<ArrayBuffer> buffer(scope, a->d()->buffer);
+ if (!buffer)
+ scope.engine->throwTypeError();
+
+ double doffset = ctx->d()->callData->argc >= 2 ? ctx->d()->callData->args[1].toInteger() : 0;
+ if (scope.engine->hasException)
+ return Encode::undefined();
+
+ if (doffset < 0 || doffset >= UINT_MAX)
+ return scope.engine->throwRangeError(QStringLiteral("TypedArray.set: out of range"));
+ uint offset = (uint)doffset;
+ uint elementSize = a->d()->type->bytesPerElement;
+
+ Scoped<TypedArray> srcTypedArray(scope, ctx->d()->callData->args[0]);
+ if (!srcTypedArray) {
+ // src is a regular object
+ ScopedObject o(scope, ctx->d()->callData->args[0].toObject(ctx));
+ if (scope.engine->hasException || !o)
+ return scope.engine->throwTypeError();
+
+ double len = ScopedValue(scope, o->get(scope.engine->id_length))->toNumber();
+ uint l = (uint)len;
+ if (scope.engine->hasException || l != len)
+ return scope.engine->throwTypeError();
+
+ if (offset + l > a->length())
+ return scope.engine->throwRangeError(QStringLiteral("TypedArray.set: out of range"));
+
+ uint idx = 0;
+ char *b = buffer->d()->data->data() + a->d()->byteOffset + offset*elementSize;
+ ScopedValue val(scope);
+ while (idx < l) {
+ val = o->getIndexed(idx);
+ a->d()->type->write(scope.engine, b, 0, val);
+ if (scope.engine->hasException)
+ return Encode::undefined();
+ ++idx;
+ b += elementSize;
+ }
+ return Encode::undefined();
+ }
+
+ // src is a typed array
+ Scoped<ArrayBuffer> srcBuffer(scope, srcTypedArray->d()->buffer);
+ if (!srcBuffer)
+ return scope.engine->throwTypeError();
+
+ uint l = srcTypedArray->length();
+ if (offset + l > a->length())
+ return scope.engine->throwRangeError(QStringLiteral("TypedArray.set: out of range"));
+
+ char *dest = buffer->d()->data->data() + a->d()->byteOffset + offset*elementSize;
+ const char *src = srcBuffer->d()->data->data() + srcTypedArray->d()->byteOffset;
+ if (srcTypedArray->d()->type == a->d()->type) {
+ // same type of typed arrays, use memmove (as srcbuffer and buffer could be the same)
+ memmove(dest, src, srcTypedArray->d()->byteLength);
+ return Encode::undefined();
+ }
+
+ char *srcCopy = 0;
+ if (buffer->d() == srcBuffer->d()) {
+ // same buffer, need to take a temporary copy, to not run into problems
+ srcCopy = new char[srcTypedArray->d()->byteLength];
+ memcpy(srcCopy, src, srcTypedArray->d()->byteLength);
+ src = srcCopy;
+ }
+
+ // typed arrays of different kind, need to manually loop
+ uint srcElementSize = srcTypedArray->d()->type->bytesPerElement;
+ TypedArrayRead read = srcTypedArray->d()->type->read;
+ TypedArrayWrite write = a->d()->type->write;
+ for (uint i = 0; i < l; ++i) {
+ Primitive val;
+ val.val = read(src, i*srcElementSize);
+ write(scope.engine, dest, i*elementSize, val);
+ }
+
+ if (srcCopy)
+ delete [] srcCopy;
+
+ return Encode::undefined();
+}
+
+ReturnedValue TypedArrayPrototype::method_subarray(CallContext *ctx)
+{
+ Scope scope(ctx);
+ Scoped<TypedArray> a(scope, ctx->d()->callData->thisObject);
+
+ if (!a)
+ return scope.engine->throwTypeError();
+
+ Scoped<ArrayBuffer> buffer(scope, a->d()->buffer);
+ if (!buffer)
+ return scope.engine->throwTypeError();
+
+ int len = a->length();
+ double b = ctx->d()->callData->argc > 0 ? ctx->d()->callData->args[0].toInteger() : 0;
+ if (b < 0)
+ b = len + b;
+ uint begin = (uint)qBound(0., b, (double)len);
+
+ double e = ctx->d()->callData->argc < 2 || ctx->d()->callData->args[1].isUndefined() ? len : ctx->d()->callData->args[1].toInteger();
+ if (e < 0)
+ e = len + e;
+ uint end = (uint)qBound(0., e, (double)len);
+ if (end < begin)
+ end = begin;
+
+ if (scope.engine->hasException)
+ return Encode::undefined();
+
+ int newLen = end - begin;
+
+ Scoped<FunctionObject> constructor(scope, a->get(scope.engine->id_constructor));
+ if (!constructor)
+ return scope.engine->throwTypeError();
+
+ ScopedCallData callData(scope, 3);
+ callData->args[0] = buffer;
+ callData->args[1] = Encode(a->d()->byteOffset + begin*a->d()->type->bytesPerElement);
+ callData->args[2] = Encode(newLen);
+ return constructor->construct(callData);
+}
diff --git a/src/qml/jsruntime/qv4typedarray_p.h b/src/qml/jsruntime/qv4typedarray_p.h
new file mode 100644
index 0000000000..28847e0c85
--- /dev/null
+++ b/src/qml/jsruntime/qv4typedarray_p.h
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QV4TYPEDARRAY_H
+#define QV4TYPEDARRAY_H
+
+#include "qv4object_p.h"
+#include "qv4functionobject_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace QV4 {
+
+struct ArrayBuffer;
+
+typedef ReturnedValue (*TypedArrayRead)(const char *data, int index);
+typedef void (*TypedArrayWrite)(ExecutionEngine *engine, char *data, int index, ValueRef value);
+
+struct TypedArrayOperations {
+ int bytesPerElement;
+ const char *name;
+ TypedArrayRead read;
+ TypedArrayWrite write;
+};
+
+struct TypedArray : Object
+{
+ enum Type {
+ Int8Array,
+ UInt8Array,
+ UInt8ClampedArray,
+ Int16Array,
+ UInt16Array,
+ Int32Array,
+ UInt32Array,
+ Float32Array,
+ Float64Array,
+ NTypes
+ };
+
+ struct Data : Object::Data {
+ Data(ExecutionEngine *e, Type t);
+
+ const TypedArrayOperations *type;
+ ArrayBuffer *buffer;
+ uint byteLength;
+ uint byteOffset;
+ };
+ V4_OBJECT(Object)
+
+ uint length() const {
+ return d()->byteLength/d()->type->bytesPerElement;
+ }
+
+
+ static void markObjects(HeapObject *that, ExecutionEngine *e);
+ static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty);
+ static void putIndexed(Managed *m, uint index, const ValueRef value);
+};
+
+struct TypedArrayCtor: FunctionObject
+{
+ struct Data : FunctionObject::Data {
+ Data(ExecutionContext *scope, TypedArray::Type t);
+
+ TypedArray::Type type;
+ };
+
+ V4_OBJECT(FunctionObject)
+
+ static ReturnedValue construct(Managed *m, CallData *callData);
+ static ReturnedValue call(Managed *that, CallData *callData);
+};
+
+
+struct TypedArrayPrototype : Object
+{
+ struct Data : Object::Data {
+ Data(ExecutionEngine *e, TypedArray::Type t)
+ : Object::Data(e)
+ , type(t)
+ {
+ setVTable(staticVTable());
+ }
+ TypedArray::Type type;
+ };
+ V4_OBJECT(Object)
+
+ void init(ExecutionEngine *engine, TypedArrayCtor *ctor);
+
+ static ReturnedValue method_get_buffer(CallContext *ctx);
+ static ReturnedValue method_get_byteLength(CallContext *ctx);
+ static ReturnedValue method_get_byteOffset(CallContext *ctx);
+ static ReturnedValue method_get_length(CallContext *ctx);
+
+ static ReturnedValue method_set(CallContext *ctx);
+ static ReturnedValue method_subarray(CallContext *ctx);
+};
+
+} // namespace QV4
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qml/jsruntime/qv4value.cpp b/src/qml/jsruntime/qv4value.cpp
index 0293054457..a80cc40add 100644
--- a/src/qml/jsruntime/qv4value.cpp
+++ b/src/qml/jsruntime/qv4value.cpp
@@ -31,6 +31,7 @@
**
****************************************************************************/
#include <qv4engine_p.h>
+#include <qv4runtime_p.h>
#ifndef V4_BOOTSTRAP
#include <qv4object_p.h>
#include <qv4objectproto_p.h>
diff --git a/src/qml/jsruntime/qv4value_inl_p.h b/src/qml/jsruntime/qv4value_inl_p.h
index 045eaccfaf..2600148417 100644
--- a/src/qml/jsruntime/qv4value_inl_p.h
+++ b/src/qml/jsruntime/qv4value_inl_p.h
@@ -35,18 +35,11 @@
#include <cmath> // this HAS to come
-#include <QtCore/QString>
-#include <QtCore/qnumeric.h>
-#include "qv4global_p.h"
+#include "qv4value_p.h"
+
#include "qv4string_p.h"
-#include <QtCore/QDebug>
#include "qv4managed_p.h"
#include "qv4engine_p.h"
-#include <private/qtqmlglobal_p.h>
-
-//#include <wtf/MathExtras.h>
-
-#include "qv4value_p.h"
QT_BEGIN_NAMESPACE
@@ -56,13 +49,13 @@ inline bool Value::isString() const
{
if (!isManaged())
return false;
- return managed() && managed()->internalClass()->vtable->isString;
+ return m && static_cast<Managed::Data *>(m)->internalClass->vtable->isString;
}
inline bool Value::isObject() const
{
if (!isManaged())
return false;
- return managed() && managed()->internalClass()->vtable->isObject;
+ return m && static_cast<Managed::Data *>(m)->internalClass->vtable->isObject;
}
inline bool Value::isPrimitive() const
@@ -70,6 +63,13 @@ inline bool Value::isPrimitive() const
return !isObject();
}
+inline String *Value::asString() const
+{
+ if (isString())
+ return stringValue();
+ return 0;
+}
+
inline ExecutionEngine *Value::engine() const
{
Managed *m = asManaged();
@@ -275,6 +275,21 @@ inline ErrorObject *Value::asErrorObject() const
template<typename T>
inline T *Value::as() const { Managed *m = isObject() ? managed() : 0; return m ? m->as<T>() : 0; }
+#ifndef V4_BOOTSTRAP
+
+template<>
+inline String *value_cast(const Value &v) {
+ return v.asString();
+}
+
+template<>
+inline ReturnedValue value_convert<String>(ExecutionEngine *e, const Value &v)
+{
+ return v.toString(e)->asReturnedValue();
+}
+
+#endif
+
#endif
} // namespace QV4
diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h
index 59a4543538..fa2d544fcf 100644
--- a/src/qml/jsruntime/qv4value_p.h
+++ b/src/qml/jsruntime/qv4value_p.h
@@ -44,19 +44,54 @@ namespace QV4 {
typedef uint Bool;
+struct Q_QML_EXPORT HeapObject {
+ HeapObject(InternalClass *internal)
+ : internalClass(internal)
+ , markBit(0)
+ , inUse(1)
+ , extensible(1)
+ {
+ // ####
+ // Q_ASSERT(internal && internal->vtable);
+ }
+ InternalClass *internalClass;
+ struct {
+ uchar markBit : 1;
+ uchar inUse : 1;
+ uchar extensible : 1; // used by Object
+ uchar _unused : 1;
+ uchar needsActivation : 1; // used by FunctionObject
+ uchar strictMode : 1; // used by FunctionObject
+ uchar bindingKeyFlag : 1;
+ uchar hasAccessorProperty : 1;
+ uchar _type;
+ mutable uchar subtype;
+ uchar _flags;
+
+ };
+
+ void setVTable(const ManagedVTable *vt);
+ inline ReturnedValue asReturnedValue() const;
+ inline void mark(QV4::ExecutionEngine *engine);
+
+ void *operator new(size_t, Managed *m) { return m; }
+ void *operator new(size_t, HeapObject *m) { return m; }
+ void operator delete(void *, HeapObject *) {}
+};
+
template <typename T>
-struct Returned : private T
+struct Returned : private HeapObject
{
- static Returned<T> *create(T *t) { return static_cast<Returned<T> *>(t); }
- T *getPointer() { return this; }
+ static Returned<T> *create(T *t) { Q_ASSERT((void *)&t->data == (void *)t); return static_cast<Returned<T> *>(static_cast<HeapObject*>(t ? &t->data : 0)); }
+ static Returned<T> *create(typename T::Data *t) { return static_cast<Returned<T> *>(static_cast<HeapObject*>(t)); }
+ T *getPointer() { return reinterpret_cast<T *>(this); }
template<typename X>
static T *getPointer(Returned<X> *x) { return x->getPointer(); }
template<typename X>
Returned<X> *as() { return Returned<X>::create(Returned<X>::getPointer(this)); }
- using T::asReturnedValue;
-};
-struct HeapObject {};
+ inline ReturnedValue asReturnedValue();
+};
struct Q_QML_PRIVATE_EXPORT Value
{
@@ -86,9 +121,7 @@ struct Q_QML_PRIVATE_EXPORT Value
union {
quint64 val;
#if QT_POINTER_SIZE == 8
- Managed *m;
- Object *o;
- String *s;
+ HeapObject *m;
#else
double dbl;
#endif
@@ -100,9 +133,7 @@ struct Q_QML_PRIVATE_EXPORT Value
uint uint_32;
int int_32;
#if QT_POINTER_SIZE == 4
- Managed *m;
- Object *o;
- String *s;
+ HeapObject *m;
#endif
};
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
@@ -270,12 +301,15 @@ struct Q_QML_PRIVATE_EXPORT Value
}
String *stringValue() const {
- return s;
+ return m ? reinterpret_cast<String*>(m) : 0;
}
Object *objectValue() const {
- return o;
+ return m ? reinterpret_cast<Object*>(m) : 0;
}
Managed *managed() const {
+ return m ? reinterpret_cast<Managed*>(m) : 0;
+ }
+ HeapObject *heapObject() const {
return m;
}
@@ -283,7 +317,17 @@ struct Q_QML_PRIVATE_EXPORT Value
return val;
}
- static inline Value fromManaged(Managed *o);
+ static inline Value fromHeapObject(HeapObject *m)
+ {
+ Value v;
+ v.m = m;
+#if QT_POINTER_SIZE == 4
+ v.tag = Managed_Type;
+#endif
+ return v;
+ }
+
+ static inline Value fromManaged(Managed *m);
int toUInt16() const;
inline int toInt32() const;
@@ -318,6 +362,12 @@ struct Q_QML_PRIVATE_EXPORT Value
inline ErrorObject *asErrorObject() const;
template<typename T> inline T *as() const;
+ template<typename T> inline T *cast() {
+ return static_cast<T *>(managed());
+ }
+ template<typename T> inline const T *cast() const {
+ return static_cast<const T *>(managed());
+ }
inline uint asArrayIndex() const;
inline uint asArrayLength(bool *ok) const;
@@ -342,7 +392,7 @@ struct Q_QML_PRIVATE_EXPORT Value
return *this;
}
Value &operator=(HeapObject *o) {
- m = reinterpret_cast<Managed *>(o);
+ m = o;
return *this;
}
@@ -364,13 +414,6 @@ inline Managed *Value::asManaged() const
return 0;
}
-inline String *Value::asString() const
-{
- if (isString())
- return stringValue();
- return 0;
-}
-
struct Q_QML_PRIVATE_EXPORT Primitive : public Value
{
inline static Primitive emptyValue();
@@ -409,20 +452,6 @@ inline Primitive Primitive::emptyValue()
return v;
}
-inline Value Value::fromManaged(Managed *m)
-{
- if (!m)
- return QV4::Primitive::undefinedValue();
- Value v;
-#if QT_POINTER_SIZE == 8
- v.m = m;
-#else
- v.tag = Managed_Type;
- v.m = m;
-#endif
- return v;
-}
-
template <typename T>
struct TypedValue : public Value
{
@@ -546,11 +575,17 @@ struct ValueRef {
ReturnedValue asReturnedValue() const { return ptr->val; }
// ### get rid of this one!
- ValueRef(Value *v) { ptr = reinterpret_cast<Value *>(v); }
+ ValueRef(Value *v) { ptr = v; }
private:
Value *ptr;
};
+inline
+ReturnedValue HeapObject::asReturnedValue() const
+{
+ return Value::fromHeapObject(const_cast<HeapObject *>(this)).asReturnedValue();
+}
+
template<typename T>
T *value_cast(const Value &v)
@@ -561,7 +596,8 @@ T *value_cast(const Value &v)
template<typename T>
ReturnedValue value_convert(ExecutionEngine *e, const Value &v);
-
+template <typename T>
+ReturnedValue Returned<T>::asReturnedValue() { return Value::fromHeapObject(this).asReturnedValue(); }
}
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index cd73314bce..35ac5eac5f 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -184,7 +184,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code
qDebug("Starting VME with context=%p and code=%p", context, code);
#endif // DO_TRACE_INSTR
- QV4::StringValue * const runtimeStrings = context->d()->compilationUnit->runtimeStrings;
+ QV4::String ** const runtimeStrings = context->d()->compilationUnit->runtimeStrings;
// setup lookup scopes
int scopeDepth = 0;
@@ -240,7 +240,7 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code
MOTH_BEGIN_INSTR(LoadRuntimeString)
// TRACE(value, "%s", instr.value.toString(context)->toQString().toUtf8().constData());
- VALUE(instr.result) = runtimeStrings[instr.stringId].asReturnedValue();
+ VALUE(instr.result) = runtimeStrings[instr.stringId]->asReturnedValue();
MOTH_END_INSTR(LoadRuntimeString)
MOTH_BEGIN_INSTR(LoadRegExp)
diff --git a/src/qml/qml/qqmlboundsignal.cpp b/src/qml/qml/qqmlboundsignal.cpp
index 26fe659616..cabb76db48 100644
--- a/src/qml/qml/qqmlboundsignal.cpp
+++ b/src/qml/qml/qqmlboundsignal.cpp
@@ -76,8 +76,8 @@ QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index,
const QString &handlerName,
const QString &parameterString)
: QQmlJavaScriptExpression(&QQmlBoundSignalExpression_jsvtable),
- m_target(target),
m_index(index),
+ m_target(target),
m_extra(new ExtraData(handlerName, parameterString, expression, fileName, line, column))
{
setExpressionFunctionValid(false);
@@ -88,9 +88,9 @@ QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index,
QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index, QQmlContextData *ctxt, QObject *scope, const QV4::ValueRef &function)
: QQmlJavaScriptExpression(&QQmlBoundSignalExpression_jsvtable),
+ m_index(index),
m_v8function(function),
m_target(target),
- m_index(index),
m_extra(0)
{
setExpressionFunctionValid(true);
@@ -101,8 +101,8 @@ QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index,
QQmlBoundSignalExpression::QQmlBoundSignalExpression(QObject *target, int index, QQmlContextData *ctxt, QObject *scope, QV4::Function *runtimeFunction)
: QQmlJavaScriptExpression(&QQmlBoundSignalExpression_jsvtable),
- m_target(target),
m_index(index),
+ m_target(target),
m_extra(0)
{
setExpressionFunctionValid(true);
diff --git a/src/qml/qml/qqmlboundsignal_p.h b/src/qml/qml/qqmlboundsignal_p.h
index b9f519a920..d2fec2afc8 100644
--- a/src/qml/qml/qqmlboundsignal_p.h
+++ b/src/qml/qml/qqmlboundsignal_p.h
@@ -98,10 +98,10 @@ private:
bool invalidParameterName() const { return m_extra.flag2(); }
void setInvalidParameterName(bool v) { m_extra.setFlag2Value(v); }
+ int m_index;
QV4::PersistentValue m_v8function;
QObject *m_target;
- int m_index;
// only needed when !expressionFunctionValid()
struct ExtraData {
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 63a43966b1..980fc99b92 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -1090,7 +1090,7 @@ struct QmlIncubatorObject : public QV4::Object
static QV4::ReturnedValue method_forceCompletion(QV4::CallContext *ctx);
static void destroy(Managed *that);
- static void markObjects(Managed *that, QV4::ExecutionEngine *e);
+ static void markObjects(QV4::HeapObject *that, QV4::ExecutionEngine *e);
void statusChanged(QQmlIncubator::Status);
void setInitialState(QObject *);
@@ -1416,7 +1416,7 @@ QV4::ReturnedValue QmlIncubatorObject::method_get_object(QV4::CallContext *ctx)
QV4::Scope scope(ctx);
QV4::Scoped<QmlIncubatorObject> o(scope, ctx->d()->callData->thisObject.as<QmlIncubatorObject>());
if (!o)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
return QV4::QObjectWrapper::wrap(ctx->d()->engine, o->d()->incubator->object());
}
@@ -1426,7 +1426,7 @@ QV4::ReturnedValue QmlIncubatorObject::method_forceCompletion(QV4::CallContext *
QV4::Scope scope(ctx);
QV4::Scoped<QmlIncubatorObject> o(scope, ctx->d()->callData->thisObject.as<QmlIncubatorObject>());
if (!o)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
o->d()->incubator->forceCompletion();
@@ -1438,7 +1438,7 @@ QV4::ReturnedValue QmlIncubatorObject::method_get_status(QV4::CallContext *ctx)
QV4::Scope scope(ctx);
QV4::Scoped<QmlIncubatorObject> o(scope, ctx->d()->callData->thisObject.as<QmlIncubatorObject>());
if (!o)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
return QV4::Encode(o->d()->incubator->status());
}
@@ -1448,7 +1448,7 @@ QV4::ReturnedValue QmlIncubatorObject::method_get_statusChanged(QV4::CallContext
QV4::Scope scope(ctx);
QV4::Scoped<QmlIncubatorObject> o(scope, ctx->d()->callData->thisObject.as<QmlIncubatorObject>());
if (!o)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
return o->d()->statusChanged.asReturnedValue();
}
@@ -1458,7 +1458,7 @@ QV4::ReturnedValue QmlIncubatorObject::method_set_statusChanged(QV4::CallContext
QV4::Scope scope(ctx);
QV4::Scoped<QmlIncubatorObject> o(scope, ctx->d()->callData->thisObject.as<QmlIncubatorObject>());
if (!o || ctx->d()->callData->argc < 1)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
o->d()->statusChanged = ctx->d()->callData->args[0];
@@ -1503,13 +1503,12 @@ void QmlIncubatorObject::destroy(Managed *that)
static_cast<QmlIncubatorObject *>(that)->d()->~Data();
}
-void QmlIncubatorObject::markObjects(QV4::Managed *that, QV4::ExecutionEngine *e)
+void QmlIncubatorObject::markObjects(QV4::HeapObject *that, QV4::ExecutionEngine *e)
{
- QmlIncubatorObject *o = static_cast<QmlIncubatorObject *>(that);
- Q_ASSERT(that->as<QmlIncubatorObject>());
- o->d()->valuemap.mark(e);
- o->d()->qmlGlobal.mark(e);
- o->d()->statusChanged.mark(e);
+ QmlIncubatorObject::Data *o = static_cast<QmlIncubatorObject::Data *>(that);
+ o->valuemap.mark(e);
+ o->qmlGlobal.mark(e);
+ o->statusChanged.mark(e);
Object::markObjects(that, e);
}
diff --git a/src/qml/qml/qqmlcontextwrapper.cpp b/src/qml/qml/qqmlcontextwrapper.cpp
index 0816bc05df..df62f285e3 100644
--- a/src/qml/qml/qqmlcontextwrapper.cpp
+++ b/src/qml/qml/qqmlcontextwrapper.cpp
@@ -291,7 +291,7 @@ void QmlContextWrapper::put(Managed *m, String *name, const ValueRef value)
QString error = QLatin1String("Invalid write to global property \"") + name->toQString() +
QLatin1Char('"');
Scoped<String> e(scope, v4->currentContext()->d()->engine->newString(error));
- v4->currentContext()->throwError(e);
+ v4->throwError(e);
return;
}
@@ -335,7 +335,7 @@ void QmlContextWrapper::put(Managed *m, String *name, const ValueRef value)
if (wrapper->d()->readOnly) {
QString error = QLatin1String("Invalid write to global property \"") + name->toQString() +
QLatin1Char('"');
- v4->currentContext()->throwError(error);
+ v4->throwError(error);
return;
}
@@ -347,11 +347,11 @@ void QmlContextWrapper::destroy(Managed *that)
static_cast<QmlContextWrapper *>(that)->d()->~Data();
}
-void QmlContextWrapper::markObjects(Managed *m, ExecutionEngine *engine)
+void QmlContextWrapper::markObjects(HeapObject *m, ExecutionEngine *engine)
{
- QmlContextWrapper *This = static_cast<QmlContextWrapper*>(m);
- if (This->d()->idObjectsWrapper)
- This->d()->idObjectsWrapper->mark(engine);
+ QmlContextWrapper::Data *This = static_cast<QmlContextWrapper::Data *>(m);
+ if (This->idObjectsWrapper)
+ This->idObjectsWrapper->mark(engine);
Object::markObjects(m, engine);
}
@@ -465,10 +465,10 @@ ReturnedValue QQmlIdObjectsArray::getIndexed(Managed *m, uint index, bool *hasPr
return QObjectWrapper::wrap(This->engine(), context->idValues[index].data());
}
-void QQmlIdObjectsArray::markObjects(Managed *that, ExecutionEngine *engine)
+void QQmlIdObjectsArray::markObjects(HeapObject *that, ExecutionEngine *engine)
{
- QQmlIdObjectsArray *This = static_cast<QQmlIdObjectsArray*>(that);
- This->d()->contextWrapper->mark(engine);
+ QQmlIdObjectsArray::Data *This = static_cast<QQmlIdObjectsArray::Data *>(that);
+ This->contextWrapper->mark(engine);
Object::markObjects(that, engine);
}
diff --git a/src/qml/qml/qqmlcontextwrapper_p.h b/src/qml/qml/qqmlcontextwrapper_p.h
index cae6800f48..ae9e795a5c 100644
--- a/src/qml/qml/qqmlcontextwrapper_p.h
+++ b/src/qml/qml/qqmlcontextwrapper_p.h
@@ -93,7 +93,7 @@ struct Q_QML_EXPORT QmlContextWrapper : Object
static ReturnedValue get(Managed *m, String *name, bool *hasProperty);
static void put(Managed *m, String *name, const ValueRef value);
static void destroy(Managed *that);
- static void markObjects(Managed *m, ExecutionEngine *engine);
+ static void markObjects(HeapObject *m, ExecutionEngine *engine);
static void registerQmlDependencies(ExecutionEngine *context, const CompiledData::Function *compiledFunction);
@@ -111,7 +111,7 @@ struct QQmlIdObjectsArray : public Object
V4_OBJECT(Object)
static ReturnedValue getIndexed(Managed *m, uint index, bool *hasProperty);
- static void markObjects(Managed *that, ExecutionEngine *engine);
+ static void markObjects(HeapObject *that, ExecutionEngine *engine);
};
diff --git a/src/qml/qml/qqmllistwrapper.cpp b/src/qml/qml/qqmllistwrapper.cpp
index 13e5e49b55..b62689c454 100644
--- a/src/qml/qml/qqmllistwrapper.cpp
+++ b/src/qml/qml/qqmllistwrapper.cpp
@@ -35,6 +35,7 @@
#include <private/qv8engine_p.h>
#include <private/qqmllist_p.h>
#include <private/qv4objectproto_p.h>
+#include <qv4objectiterator_p.h>
#include <private/qv4functionobject_p.h>
diff --git a/src/qml/qml/qqmllocale_p.h b/src/qml/qml/qqmllocale_p.h
index 3787517038..233624453f 100644
--- a/src/qml/qml/qqmllocale_p.h
+++ b/src/qml/qml/qqmllocale_p.h
@@ -137,7 +137,7 @@ struct QQmlLocaleData : public QV4::Object
QV4::Object *o = ctx->d()->callData->thisObject.asObject();
QQmlLocaleData *thisObject = o ? o->as<QQmlLocaleData>() : 0;
if (!thisObject) {
- ctx->throwTypeError();
+ ctx->engine()->throwTypeError();
return 0;
}
return &thisObject->d()->locale;
diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp
index d8f282c030..ddd934c840 100644
--- a/src/qml/qml/qqmltypewrapper.cpp
+++ b/src/qml/qml/qqmltypewrapper.cpp
@@ -262,7 +262,7 @@ void QmlTypeWrapper::put(Managed *m, String *name, const ValueRef value)
QV4::ScopedObject apiprivate(scope, QJSValuePrivate::get(siinfo->scriptApi(e))->value);
if (!apiprivate) {
QString error = QLatin1String("Cannot assign to read-only property \"") + name->toQString() + QLatin1Char('\"');
- v4->currentContext()->throwError(error);
+ v4->throwError(error);
return;
} else {
apiprivate->put(name, value);
diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp
index b0125b4c13..7de15eac7d 100644
--- a/src/qml/qml/qqmlvaluetypewrapper.cpp
+++ b/src/qml/qml/qqmlvaluetypewrapper.cpp
@@ -144,7 +144,7 @@ ReturnedValue QmlValueTypeWrapper::create(QV8Engine *v8, QObject *object, int pr
Scope scope(v4);
initProto(v4);
- QmlValueTypeReference *r = v4->memoryManager->alloc<QmlValueTypeReference>(v8);
+ Scoped<QmlValueTypeReference> r(scope, v4->memoryManager->alloc<QmlValueTypeReference>(v8));
r->d()->internalClass = r->d()->internalClass->changePrototype(v4->qmlExtensions()->valueTypeWrapperPrototype);
r->d()->type = type; r->d()->object = object; r->d()->property = property;
return r->asReturnedValue();
@@ -156,7 +156,7 @@ ReturnedValue QmlValueTypeWrapper::create(QV8Engine *v8, const QVariant &value,
Scope scope(v4);
initProto(v4);
- QmlValueTypeCopy *r = v4->memoryManager->alloc<QmlValueTypeCopy>(v8);
+ Scoped<QmlValueTypeCopy> r(scope, v4->memoryManager->alloc<QmlValueTypeCopy>(v8));
r->d()->internalClass = r->d()->internalClass->changePrototype(v4->qmlExtensions()->valueTypeWrapperPrototype);
r->d()->type = type; r->d()->value = value;
return r->asReturnedValue();
@@ -242,10 +242,10 @@ ReturnedValue QmlValueTypeWrapper::method_toString(CallContext *ctx)
{
Object *o = ctx->d()->callData->thisObject.asObject();
if (!o)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
QmlValueTypeWrapper *w = o->as<QmlValueTypeWrapper>();
if (!w)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
if (w->d()->objectType == QmlValueTypeWrapper::Reference) {
QmlValueTypeReference *reference = static_cast<QmlValueTypeReference *>(w);
@@ -355,7 +355,7 @@ void QmlValueTypeWrapper::put(Managed *m, String *name, const ValueRef value)
// assigning a JS function to a non-var-property is not allowed.
QString error = QLatin1String("Cannot assign JavaScript function to value-type property");
Scoped<String> e(scope, r->d()->v8->toString(error));
- v4->currentContext()->throwError(e);
+ v4->throwError(e);
return;
}
diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp
index 0730cbc363..2acd40ae44 100644
--- a/src/qml/qml/qqmlxmlhttprequest.cpp
+++ b/src/qml/qml/qqmlxmlhttprequest.cpp
@@ -55,6 +55,7 @@
#include <QtCore/qxmlstream.h>
#include <QtCore/qstack.h>
#include <QtCore/qdebug.h>
+#include <QtCore/qbuffer.h>
#include <private/qv4objectproto_p.h>
#include <private/qv4scopedvalue_p.h>
@@ -65,7 +66,7 @@ using namespace QV4;
#define V4THROW_REFERENCE(string) { \
Scoped<Object> error(scope, ctx->engine()->newReferenceErrorObject(QStringLiteral(string))); \
- return ctx->throwError(error); \
+ return ctx->engine()->throwError(error); \
}
QT_BEGIN_NAMESPACE
@@ -420,7 +421,7 @@ ReturnedValue NodePrototype::method_get_nodeName(CallContext *ctx)
Scope scope(ctx);
Scoped<Node> r(scope, ctx->d()->callData->thisObject.as<Node>());
if (!r)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
QString name;
switch (r->d()->d->type) {
@@ -445,7 +446,7 @@ ReturnedValue NodePrototype::method_get_nodeValue(CallContext *ctx)
Scope scope(ctx);
Scoped<Node> r(scope, ctx->d()->callData->thisObject.as<Node>());
if (!r)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
if (r->d()->d->type == NodeImpl::Document ||
r->d()->d->type == NodeImpl::DocumentFragment ||
@@ -464,7 +465,7 @@ ReturnedValue NodePrototype::method_get_nodeType(CallContext *ctx)
Scope scope(ctx);
Scoped<Node> r(scope, ctx->d()->callData->thisObject.as<Node>());
if (!r)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
return Encode(r->d()->d->type);
}
@@ -474,7 +475,7 @@ ReturnedValue NodePrototype::method_get_parentNode(CallContext *ctx)
Scope scope(ctx);
Scoped<Node> r(scope, ctx->d()->callData->thisObject.as<Node>());
if (!r)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
QV8Engine *engine = ctx->d()->engine->v8Engine;
@@ -489,7 +490,7 @@ ReturnedValue NodePrototype::method_get_childNodes(CallContext *ctx)
Scope scope(ctx);
Scoped<Node> r(scope, ctx->d()->callData->thisObject.as<Node>());
if (!r)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
QV8Engine *engine = ctx->d()->engine->v8Engine;
@@ -501,7 +502,7 @@ ReturnedValue NodePrototype::method_get_firstChild(CallContext *ctx)
Scope scope(ctx);
Scoped<Node> r(scope, ctx->d()->callData->thisObject.as<Node>());
if (!r)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
QV8Engine *engine = ctx->d()->engine->v8Engine;
@@ -516,7 +517,7 @@ ReturnedValue NodePrototype::method_get_lastChild(CallContext *ctx)
Scope scope(ctx);
Scoped<Node> r(scope, ctx->d()->callData->thisObject.as<Node>());
if (!r)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
QV8Engine *engine = ctx->d()->engine->v8Engine;
@@ -531,7 +532,7 @@ ReturnedValue NodePrototype::method_get_previousSibling(CallContext *ctx)
Scope scope(ctx);
Scoped<Node> r(scope, ctx->d()->callData->thisObject.as<Node>());
if (!r)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
QV8Engine *engine = ctx->d()->engine->v8Engine;
@@ -555,7 +556,7 @@ ReturnedValue NodePrototype::method_get_nextSibling(CallContext *ctx)
Scope scope(ctx);
Scoped<Node> r(scope, ctx->d()->callData->thisObject.as<Node>());
if (!r)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
QV8Engine *engine = ctx->d()->engine->v8Engine;
@@ -579,7 +580,7 @@ ReturnedValue NodePrototype::method_get_attributes(CallContext *ctx)
Scope scope(ctx);
Scoped<Node> r(scope, ctx->d()->callData->thisObject.as<Node>());
if (!r)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
QV8Engine *engine = ctx->d()->engine->v8Engine;
@@ -899,7 +900,7 @@ ReturnedValue NamedNodeMap::getIndexed(Managed *m, uint index, bool *hasProperty
if (!r) {
if (hasProperty)
*hasProperty = false;
- return v4->currentContext()->throwTypeError();
+ return v4->throwTypeError();
}
QV8Engine *engine = v4->v8Engine;
@@ -1249,16 +1250,23 @@ void QQmlXMLHttpRequest::requestFromUrl(const QUrl &url)
}
}
- if (m_method == QLatin1String("GET"))
+ if (m_method == QLatin1String("GET")) {
m_network = networkAccessManager()->get(request);
- else if (m_method == QLatin1String("HEAD"))
+ } else if (m_method == QLatin1String("HEAD")) {
m_network = networkAccessManager()->head(request);
- else if (m_method == QLatin1String("POST"))
+ } else if (m_method == QLatin1String("POST")) {
m_network = networkAccessManager()->post(request, m_data);
- else if (m_method == QLatin1String("PUT"))
+ } else if (m_method == QLatin1String("PUT")) {
m_network = networkAccessManager()->put(request, m_data);
- else if (m_method == QLatin1String("DELETE"))
+ } else if (m_method == QLatin1String("DELETE")) {
m_network = networkAccessManager()->deleteResource(request);
+ } else if (m_method == QLatin1String("OPTIONS")) {
+ QBuffer *buffer = new QBuffer;
+ buffer->setData(m_data);
+ buffer->open(QIODevice::ReadOnly);
+ m_network = networkAccessManager()->sendCustomRequest(request, QByteArrayLiteral("OPTIONS"), buffer);
+ buffer->setParent(m_network);
+ }
QObject::connect(m_network, SIGNAL(readyRead()),
this, SLOT(readyRead()));
@@ -1526,14 +1534,14 @@ void QQmlXMLHttpRequest::dispatchCallbackImpl(const ValueRef me)
QV4::Scope scope(v4);
Scoped<Object> o(scope, me);
if (!o) {
- ctx->throwError(QStringLiteral("QQmlXMLHttpRequest: internal error: empty ThisObject"));
+ ctx->engine()->throwError(QStringLiteral("QQmlXMLHttpRequest: internal error: empty ThisObject"));
return;
}
ScopedString s(scope, v4->newString(QStringLiteral("ThisObject")));
Scoped<Object> thisObj(scope, o->get(s.getPointer()));
if (!thisObj) {
- ctx->throwError(QStringLiteral("QQmlXMLHttpRequest: internal error: empty ThisObject"));
+ ctx->engine()->throwError(QStringLiteral("QQmlXMLHttpRequest: internal error: empty ThisObject"));
return;
}
@@ -1547,7 +1555,7 @@ void QQmlXMLHttpRequest::dispatchCallbackImpl(const ValueRef me)
s = v4->newString(QStringLiteral("ActivationObject"));
Scoped<Object> activationObject(scope, o->get(s.getPointer()));
if (!activationObject) {
- v4->currentContext()->throwError(QStringLiteral("QQmlXMLHttpRequest: internal error: empty ActivationObject"));
+ v4->throwError(QStringLiteral("QQmlXMLHttpRequest: internal error: empty ActivationObject"));
return;
}
@@ -1631,10 +1639,10 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject
Object *proto;
};
V4_OBJECT(FunctionObject)
- static void markObjects(Managed *that, ExecutionEngine *e) {
- QQmlXMLHttpRequestCtor *c = static_cast<QQmlXMLHttpRequestCtor *>(that);
- if (c->d()->proto)
- c->d()->proto->mark(e);
+ static void markObjects(HeapObject *that, ExecutionEngine *e) {
+ QQmlXMLHttpRequestCtor::Data *c = static_cast<QQmlXMLHttpRequestCtor::Data *>(that);
+ if (c->proto)
+ c->proto->mark(e);
FunctionObject::markObjects(that, e);
}
static ReturnedValue construct(Managed *that, QV4::CallData *)
@@ -1642,7 +1650,7 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject
Scope scope(that->engine());
Scoped<QQmlXMLHttpRequestCtor> ctor(scope, that->as<QQmlXMLHttpRequestCtor>());
if (!ctor)
- return that->engine()->currentContext()->throwTypeError();
+ return that->engine()->throwTypeError();
QV8Engine *engine = that->engine()->v8Engine;
QQmlXMLHttpRequest *r = new QQmlXMLHttpRequest(engine, engine->networkAccessManager());
@@ -1724,7 +1732,8 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_open(CallContext *ctx)
method != QLatin1String("PUT") &&
method != QLatin1String("HEAD") &&
method != QLatin1String("POST") &&
- method != QLatin1String("DELETE"))
+ method != QLatin1String("DELETE") &&
+ method != QLatin1String("OPTIONS"))
V4THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Unsupported HTTP method type");
// Argument 1 - URL
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index f222d59494..3a593d1c5b 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -1004,7 +1004,7 @@ ReturnedValue QtObject::method_createQmlObject(CallContext *ctx)
if (component.isError()) {
ScopedValue v(scope, Error::create(ctx->d()->engine, component.errors()));
- return ctx->throwError(v);
+ return ctx->engine()->throwError(v);
}
if (!component.isReady())
@@ -1028,7 +1028,7 @@ ReturnedValue QtObject::method_createQmlObject(CallContext *ctx)
if (component.isError()) {
ScopedValue v(scope, Error::create(ctx->d()->engine, component.errors()));
- return ctx->throwError(v);
+ return ctx->engine()->throwError(v);
}
Q_ASSERT(obj);
@@ -1070,7 +1070,7 @@ use \l{QtQml::Qt::createQmlObject()}{Qt.createQmlObject()}.
ReturnedValue QtObject::method_createComponent(CallContext *ctx)
{
if (ctx->d()->callData->argc < 1 || ctx->d()->callData->argc > 3)
- return ctx->throwError(QStringLiteral("Qt.createComponent(): Invalid arguments"));
+ return ctx->engine()->throwError(QStringLiteral("Qt.createComponent(): Invalid arguments"));
Scope scope(ctx);
@@ -1098,13 +1098,13 @@ ReturnedValue QtObject::method_createComponent(CallContext *ctx)
if (ctx->d()->callData->args[1].isInteger()) {
int mode = ctx->d()->callData->args[1].integerValue();
if (mode != int(QQmlComponent::PreferSynchronous) && mode != int(QQmlComponent::Asynchronous))
- return ctx->throwError(QStringLiteral("Qt.createComponent(): Invalid arguments"));
+ return ctx->engine()->throwError(QStringLiteral("Qt.createComponent(): Invalid arguments"));
compileMode = QQmlComponent::CompilationMode(mode);
consumedCount += 1;
} else {
// The second argument could be the parent only if there are exactly two args
if ((ctx->d()->callData->argc != 2) || !(lastArg->isObject() || lastArg->isNull()))
- return ctx->throwError(QStringLiteral("Qt.createComponent(): Invalid arguments"));
+ return ctx->engine()->throwError(QStringLiteral("Qt.createComponent(): Invalid arguments"));
}
if (consumedCount < ctx->d()->callData->argc) {
@@ -1113,11 +1113,11 @@ ReturnedValue QtObject::method_createComponent(CallContext *ctx)
if (qobjectWrapper)
parentArg = qobjectWrapper->object();
if (!parentArg)
- return ctx->throwError(QStringLiteral("Qt.createComponent(): Invalid parent object"));
+ return ctx->engine()->throwError(QStringLiteral("Qt.createComponent(): Invalid parent object"));
} else if (lastArg->isNull()) {
parentArg = 0;
} else {
- return ctx->throwError(QStringLiteral("Qt.createComponent(): Invalid parent object"));
+ return ctx->engine()->throwError(QStringLiteral("Qt.createComponent(): Invalid parent object"));
}
}
}
@@ -1187,10 +1187,10 @@ ReturnedValue QQmlBindingFunction::call(Managed *that, CallData *callData)
return This->d()->originalFunction->call(callData);
}
-void QQmlBindingFunction::markObjects(Managed *that, ExecutionEngine *e)
+void QQmlBindingFunction::markObjects(HeapObject *that, ExecutionEngine *e)
{
- QQmlBindingFunction *This = static_cast<QQmlBindingFunction*>(that);
- This->d()->originalFunction->mark(e);
+ QQmlBindingFunction::Data *This = static_cast<QQmlBindingFunction::Data *>(that);
+ This->originalFunction->mark(e);
QV4::FunctionObject::markObjects(that, e);
}
@@ -1257,10 +1257,10 @@ ReturnedValue QtObject::method_get_platform(CallContext *ctx)
// ### inefficient. Should be just a value based getter
Object *o = ctx->d()->callData->thisObject.asObject();
if (!o)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
QtObject *qt = o->as<QtObject>();
if (!qt)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
if (!qt->d()->platform)
// Only allocate a platform object once
@@ -1274,10 +1274,10 @@ ReturnedValue QtObject::method_get_application(CallContext *ctx)
// ### inefficient. Should be just a value based getter
Object *o = ctx->d()->callData->thisObject.asObject();
if (!o)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
QtObject *qt = o->as<QtObject>();
if (!qt)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
if (!qt->d()->application)
// Only allocate an application object once
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
index f7728aa120..7fe7d2b914 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
@@ -155,7 +155,7 @@ struct QQmlBindingFunction : public QV4::FunctionObject
static ReturnedValue call(Managed *that, CallData *callData);
- static void markObjects(Managed *that, ExecutionEngine *e);
+ static void markObjects(HeapObject *that, ExecutionEngine *e);
static void destroy(Managed *that) {
static_cast<QQmlBindingFunction *>(that)->d()->~Data();
}
diff --git a/src/qml/qml/v8/qv4domerrors_p.h b/src/qml/qml/v8/qv4domerrors_p.h
index 59ed744f5e..facf7972ad 100644
--- a/src/qml/qml/v8/qv4domerrors_p.h
+++ b/src/qml/qml/v8/qv4domerrors_p.h
@@ -72,7 +72,7 @@ QT_BEGIN_NAMESPACE
QV4::ScopedValue v(scope, scope.engine->newString(QStringLiteral(string))); \
QV4::Scoped<Object> ex(scope, scope.engine->newErrorObject(v)); \
ex->put(QV4::ScopedString(scope, scope.engine->newIdentifier(QStringLiteral("code"))).getPointer(), QV4::ScopedValue(scope, QV4::Primitive::fromInt32(error))); \
- return ctx->throwError(ex); \
+ return ctx->engine()->throwError(ex); \
}
namespace QV4 {
diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp
index 39b816f97c..d472120b4e 100644
--- a/src/qml/qml/v8/qv8engine.cpp
+++ b/src/qml/qml/v8/qv8engine.cpp
@@ -305,21 +305,6 @@ QVariant QV8Engine::objectToVariant(QV4::Object *o, V8ObjectSet *visitedObjects)
return result;
}
-static QV4::ReturnedValue arrayFromStringList(QV8Engine *engine, const QStringList &list)
-{
- QV4::ExecutionEngine *e = QV8Engine::getV4(engine);
- QV4::Scope scope(e);
- QV4::Scoped<QV4::ArrayObject> a(scope, e->newArrayObject());
- int len = list.count();
- a->arrayReserve(len);
- QV4::ScopedValue v(scope);
- for (int ii = 0; ii < len; ++ii)
- a->arrayPut(ii, (v = QV4::Encode(e->newString(list.at(ii)))));
-
- a->setArrayLengthUnchecked(len);
- return a.asReturnedValue();
-}
-
static QV4::ReturnedValue arrayFromVariantList(QV8Engine *engine, const QVariantList &list)
{
QV4::ExecutionEngine *e = QV8Engine::getV4(engine);
@@ -409,7 +394,7 @@ QV4::ReturnedValue QV8Engine::fromVariant(const QVariant &variant)
QV4::ScopedValue retn(scope, QV4::SequencePrototype::fromVariant(m_v4Engine, variant, &succeeded));
if (succeeded)
return retn.asReturnedValue();
- return arrayFromStringList(this, *reinterpret_cast<const QStringList *>(ptr));
+ return QV4::Encode(m_v4Engine->newArrayObject(*reinterpret_cast<const QStringList *>(ptr)));
}
case QMetaType::QVariantList:
return arrayFromVariantList(this, *reinterpret_cast<const QVariantList *>(ptr));
diff --git a/src/qml/qml/v8/qv8engine_p.h b/src/qml/qml/v8/qv8engine_p.h
index 51e857c8a2..2379689fb3 100644
--- a/src/qml/qml/v8/qv8engine_p.h
+++ b/src/qml/qml/v8/qv8engine_p.h
@@ -78,10 +78,10 @@ namespace QV4 {
// #define QML_GLOBAL_HANDLE_DEBUGGING
#define V4THROW_ERROR(string) \
- return ctx->throwError(QString::fromUtf8(string));
+ return ctx->engine()->throwError(QString::fromUtf8(string));
#define V4THROW_TYPE(string) \
- return ctx->throwTypeError(QStringLiteral(string));
+ return ctx->engine()->throwTypeError(QStringLiteral(string));
#define V8_DEFINE_EXTENSION(dataclass, datafunction) \
static inline dataclass *datafunction(QV8Engine *engine) \
diff --git a/src/qml/qml/v8/v8.pri b/src/qml/qml/v8/v8.pri
index b4eb706574..3d6a012481 100644
--- a/src/qml/qml/v8/v8.pri
+++ b/src/qml/qml/v8/v8.pri
@@ -1,5 +1,4 @@
HEADERS += \
- $$PWD/qv8debug_p.h \
$$PWD/qv8engine_p.h \
$$PWD/qv4domerrors_p.h \
$$PWD/qv4sqlerrors_p.h \
diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp
index 639df4f846..e150545926 100644
--- a/src/qml/types/qqmldelegatemodel.cpp
+++ b/src/qml/types/qqmldelegatemodel.cpp
@@ -46,6 +46,7 @@
#include <private/qv4value_inl_p.h>
#include <private/qv4functionobject_p.h>
+#include <qv4objectiterator_p.h>
QT_BEGIN_NAMESPACE
@@ -67,14 +68,14 @@ struct DelegateModelGroupFunction: QV4::FunctionObject
};
V4_OBJECT(QV4::FunctionObject)
- static DelegateModelGroupFunction *create(QV4::ExecutionContext *scope, uint flag, QV4::ReturnedValue (*code)(QQmlDelegateModelItem *item, uint flag, const QV4::ValueRef arg))
+ static QV4::Returned<DelegateModelGroupFunction> *create(QV4::ExecutionContext *scope, uint flag, QV4::ReturnedValue (*code)(QQmlDelegateModelItem *item, uint flag, const QV4::ValueRef arg))
{
return scope->engine()->memoryManager->alloc<DelegateModelGroupFunction>(scope, flag, code);
}
static QV4::ReturnedValue construct(QV4::Managed *m, QV4::CallData *)
{
- return m->engine()->currentContext()->throwTypeError();
+ return m->engine()->throwTypeError();
}
static QV4::ReturnedValue call(QV4::Managed *that, QV4::CallData *callData)
@@ -84,7 +85,7 @@ struct DelegateModelGroupFunction: QV4::FunctionObject
QV4::Scoped<DelegateModelGroupFunction> f(scope, that, QV4::Scoped<DelegateModelGroupFunction>::Cast);
QV4::Scoped<QQmlDelegateModelItemObject> o(scope, callData->thisObject);
if (!o)
- return v4->currentContext()->throwTypeError(QStringLiteral("Not a valid VisualData object"));
+ return v4->throwTypeError(QStringLiteral("Not a valid VisualData object"));
QV4::ScopedValue v(scope, callData->argument(0));
return f->d()->code(o->d()->item, f->d()->flag, v);
@@ -1780,7 +1781,7 @@ QV4::ReturnedValue QQmlDelegateModelItem::get_model(QV4::CallContext *ctx)
QV4::Scope scope(ctx);
QV4::Scoped<QQmlDelegateModelItemObject> o(scope, ctx->d()->callData->thisObject.as<QQmlDelegateModelItemObject>());
if (!o)
- return ctx->throwTypeError(QStringLiteral("Not a valid VisualData object"));
+ return ctx->engine()->throwTypeError(QStringLiteral("Not a valid VisualData object"));
if (!o->d()->item->metaType->model)
return QV4::Encode::undefined();
@@ -1792,7 +1793,7 @@ QV4::ReturnedValue QQmlDelegateModelItem::get_groups(QV4::CallContext *ctx)
QV4::Scope scope(ctx);
QV4::Scoped<QQmlDelegateModelItemObject> o(scope, ctx->d()->callData->thisObject.as<QQmlDelegateModelItemObject>());
if (!o)
- return ctx->throwTypeError(QStringLiteral("Not a valid VisualData object"));
+ return ctx->engine()->throwTypeError(QStringLiteral("Not a valid VisualData object"));
QStringList groups;
for (int i = 1; i < o->d()->item->metaType->groupCount; ++i) {
@@ -1808,9 +1809,9 @@ QV4::ReturnedValue QQmlDelegateModelItem::set_groups(QV4::CallContext *ctx)
QV4::Scope scope(ctx);
QV4::Scoped<QQmlDelegateModelItemObject> o(scope, ctx->d()->callData->thisObject.as<QQmlDelegateModelItemObject>());
if (!o)
- return ctx->throwTypeError(QStringLiteral("Not a valid VisualData object"));
+ return ctx->engine()->throwTypeError(QStringLiteral("Not a valid VisualData object"));
if (!ctx->d()->callData->argc)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
if (!o->d()->item->metaType->model)
return QV4::Encode::undefined();
@@ -3220,7 +3221,7 @@ struct QQmlDelegateModelGroupChange : QV4::Object
};
V4_OBJECT(QV4::Object)
- static QQmlDelegateModelGroupChange *create(QV4::ExecutionEngine *e) {
+ static QV4::Returned<QQmlDelegateModelGroupChange> *create(QV4::ExecutionEngine *e) {
return e->memoryManager->alloc<QQmlDelegateModelGroupChange>(e);
}
@@ -3228,21 +3229,21 @@ struct QQmlDelegateModelGroupChange : QV4::Object
QV4::Scope scope(ctx);
QV4::Scoped<QQmlDelegateModelGroupChange> that(scope, ctx->d()->callData->thisObject.as<QQmlDelegateModelGroupChange>());
if (!that)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
return QV4::Encode(that->d()->change.index);
}
static QV4::ReturnedValue method_get_count(QV4::CallContext *ctx) {
QV4::Scope scope(ctx);
QV4::Scoped<QQmlDelegateModelGroupChange> that(scope, ctx->d()->callData->thisObject.as<QQmlDelegateModelGroupChange>());
if (!that)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
return QV4::Encode(that->d()->change.count);
}
static QV4::ReturnedValue method_get_moveId(QV4::CallContext *ctx) {
QV4::Scope scope(ctx);
QV4::Scoped<QQmlDelegateModelGroupChange> that(scope, ctx->d()->callData->thisObject.as<QQmlDelegateModelGroupChange>());
if (!that)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
if (that->d()->change.moveId < 0)
return QV4::Encode::undefined();
return QV4::Encode(that->d()->change.moveId);
@@ -3267,7 +3268,7 @@ struct QQmlDelegateModelGroupChangeArray : public QV4::Object
};
V4_OBJECT(QV4::Object)
public:
- static QQmlDelegateModelGroupChangeArray *create(QV4::ExecutionEngine *engine, const QVector<QQmlChangeSet::Change> &changes)
+ static QV4::Returned<QQmlDelegateModelGroupChangeArray> *create(QV4::ExecutionEngine *engine, const QVector<QQmlChangeSet::Change> &changes)
{
return engine->memoryManager->alloc<QQmlDelegateModelGroupChangeArray>(engine, changes);
}
diff --git a/src/qml/util/qqmladaptormodel.cpp b/src/qml/util/qqmladaptormodel.cpp
index b147f56bfa..943947f577 100644
--- a/src/qml/util/qqmladaptormodel.cpp
+++ b/src/qml/util/qqmladaptormodel.cpp
@@ -60,7 +60,7 @@ static QV4::ReturnedValue get_index(QV4::CallContext *ctx)
QV4::Scope scope(ctx);
QV4::Scoped<QQmlDelegateModelItemObject> o(scope, ctx->d()->callData->thisObject.as<QQmlDelegateModelItemObject>());
if (!o)
- return ctx->throwTypeError(QStringLiteral("Not a valid VisualData object"));
+ return ctx->engine()->throwTypeError(QStringLiteral("Not a valid VisualData object"));
return QV4::Encode(o->d()->item->index);
}
@@ -192,7 +192,7 @@ public:
QV4::Scope scope(ctx);
QV4::Scoped<QQmlDelegateModelItemObject> o(scope, ctx->d()->callData->thisObject.as<QQmlDelegateModelItemObject>());
if (!o)
- return ctx->throwTypeError(QStringLiteral("Not a valid VisualData object"));
+ return ctx->engine()->throwTypeError(QStringLiteral("Not a valid VisualData object"));
const QQmlAdaptorModel *const model = static_cast<QQmlDMCachedModelData *>(o->d()->item)->type->model;
if (o->d()->item->index >= 0 && *model) {
@@ -339,7 +339,7 @@ QV4::ReturnedValue QQmlDMCachedModelData::get_property(QV4::CallContext *ctx, ui
QV4::Scope scope(ctx);
QV4::Scoped<QQmlDelegateModelItemObject> o(scope, ctx->d()->callData->thisObject.as<QQmlDelegateModelItemObject>());
if (!o)
- return ctx->throwTypeError(QStringLiteral("Not a valid VisualData object"));
+ return ctx->engine()->throwTypeError(QStringLiteral("Not a valid VisualData object"));
QQmlDMCachedModelData *modelData = static_cast<QQmlDMCachedModelData *>(o->d()->item);
if (o->d()->item->index == -1) {
@@ -359,9 +359,9 @@ QV4::ReturnedValue QQmlDMCachedModelData::set_property(QV4::CallContext *ctx, ui
QV4::Scope scope(ctx);
QV4::Scoped<QQmlDelegateModelItemObject> o(scope, ctx->d()->callData->thisObject.as<QQmlDelegateModelItemObject>());
if (!o)
- return ctx->throwTypeError(QStringLiteral("Not a valid VisualData object"));
+ return ctx->engine()->throwTypeError(QStringLiteral("Not a valid VisualData object"));
if (!ctx->d()->callData->argc)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
if (o->d()->item->index == -1) {
QQmlDMCachedModelData *modelData = static_cast<QQmlDMCachedModelData *>(o->d()->item);
@@ -581,7 +581,7 @@ public:
QV4::Scope scope(ctx);
QV4::Scoped<QQmlDelegateModelItemObject> o(scope, ctx->d()->callData->thisObject.as<QQmlDelegateModelItemObject>());
if (!o)
- return ctx->throwTypeError(QStringLiteral("Not a valid VisualData object"));
+ return ctx->engine()->throwTypeError(QStringLiteral("Not a valid VisualData object"));
return scope.engine->v8Engine->fromVariant(static_cast<QQmlDMListAccessorData *>(o->d()->item)->cachedData);
}
@@ -591,9 +591,9 @@ public:
QV4::Scope scope(ctx);
QV4::Scoped<QQmlDelegateModelItemObject> o(scope, ctx->d()->callData->thisObject.as<QQmlDelegateModelItemObject>());
if (!o)
- return ctx->throwTypeError(QStringLiteral("Not a valid VisualData object"));
+ return ctx->engine()->throwTypeError(QStringLiteral("Not a valid VisualData object"));
if (!ctx->d()->callData->argc)
- return ctx->throwTypeError();
+ return ctx->engine()->throwTypeError();
static_cast<QQmlDMListAccessorData *>(o->d()->item)->setModelData(scope.engine->v8Engine->toVariant(ctx->d()->callData->args[0], QVariant::Invalid));
return QV4::Encode::undefined();