aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2017-01-25 14:30:30 +0100
committerLaszlo Agocs <laszlo.agocs@qt.io>2017-01-25 14:31:06 +0100
commit00d3f3e9da071efce92d320884b331ea559fb292 (patch)
tree0649bd5c1be5a8ca01617655ac54c6373322f14a /src
parent5c2ba6db53b2190160081695faff521bc367e33d (diff)
parentb07a6cf8c5788b7e4ca722c9aa8c06e76e688c5d (diff)
Merge remote-tracking branch 'origin/dev' into wip/scenegraphng
Diffstat (limited to 'src')
-rw-r--r--src/plugins/scenegraph/openvg/openvg.pro1
-rw-r--r--src/plugins/scenegraph/openvg/qopenvgoffscreensurface.cpp5
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgcontext.cpp4
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.cpp73
-rw-r--r--src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.h32
-rw-r--r--src/qml/compiler/qv4codegen.cpp8
-rw-r--r--src/qml/jsruntime/qv4arraybuffer.cpp69
-rw-r--r--src/qml/jsruntime/qv4arraybuffer_p.h8
-rw-r--r--src/qml/jsruntime/qv4arraydata.cpp10
-rw-r--r--src/qml/jsruntime/qv4arrayobject.cpp675
-rw-r--r--src/qml/jsruntime/qv4arrayobject_p.h48
-rw-r--r--src/qml/jsruntime/qv4booleanobject.cpp26
-rw-r--r--src/qml/jsruntime/qv4booleanobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4context.cpp34
-rw-r--r--src/qml/jsruntime/qv4context_p.h24
-rw-r--r--src/qml/jsruntime/qv4dataview.cpp133
-rw-r--r--src/qml/jsruntime/qv4dataview_p.h18
-rw-r--r--src/qml/jsruntime/qv4dateobject.cpp475
-rw-r--r--src/qml/jsruntime/qv4dateobject_p.h102
-rw-r--r--src/qml/jsruntime/qv4errorobject.cpp25
-rw-r--r--src/qml/jsruntime/qv4errorobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4functionobject.cpp134
-rw-r--r--src/qml/jsruntime/qv4functionobject_p.h32
-rw-r--r--src/qml/jsruntime/qv4global_p.h1
-rw-r--r--src/qml/jsruntime/qv4globalobject.cpp146
-rw-r--r--src/qml/jsruntime/qv4globalobject_p.h20
-rw-r--r--src/qml/jsruntime/qv4include.cpp19
-rw-r--r--src/qml/jsruntime/qv4include_p.h2
-rw-r--r--src/qml/jsruntime/qv4internalclass.cpp32
-rw-r--r--src/qml/jsruntime/qv4jsonobject.cpp23
-rw-r--r--src/qml/jsruntime/qv4jsonobject_p.h4
-rw-r--r--src/qml/jsruntime/qv4mathobject.cpp186
-rw-r--r--src/qml/jsruntime/qv4mathobject_p.h38
-rw-r--r--src/qml/jsruntime/qv4memberdata.cpp6
-rw-r--r--src/qml/jsruntime/qv4numberobject.cpp160
-rw-r--r--src/qml/jsruntime/qv4numberobject_p.h16
-rw-r--r--src/qml/jsruntime/qv4object.cpp53
-rw-r--r--src/qml/jsruntime/qv4object_p.h14
-rw-r--r--src/qml/jsruntime/qv4objectproto.cpp412
-rw-r--r--src/qml/jsruntime/qv4objectproto_p.h52
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp65
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper_p.h4
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp94
-rw-r--r--src/qml/jsruntime/qv4regexpobject_p.h18
-rw-r--r--src/qml/jsruntime/qv4scopedvalue_p.h32
-rw-r--r--src/qml/jsruntime/qv4sequenceobject.cpp64
-rw-r--r--src/qml/jsruntime/qv4sequenceobject_p.h6
-rw-r--r--src/qml/jsruntime/qv4stringobject.cpp395
-rw-r--r--src/qml/jsruntime/qv4stringobject_p.h46
-rw-r--r--src/qml/jsruntime/qv4typedarray.cpp101
-rw-r--r--src/qml/jsruntime/qv4typedarray_p.h12
-rw-r--r--src/qml/jsruntime/qv4variantobject.cpp47
-rw-r--r--src/qml/jsruntime/qv4variantobject_p.h8
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp4
-rw-r--r--src/qml/memory/memory.pri4
-rw-r--r--src/qml/memory/qv4heap_p.h43
-rw-r--r--src/qml/memory/qv4mm.cpp929
-rw-r--r--src/qml/memory/qv4mm_p.h196
-rw-r--r--src/qml/memory/qv4mmdefs_p.h262
-rw-r--r--src/qml/qml/qqmlcomponent.cpp59
-rw-r--r--src/qml/qml/qqmldelayedcallqueue.cpp10
-rw-r--r--src/qml/qml/qqmldelayedcallqueue_p.h2
-rw-r--r--src/qml/qml/qqmldirparser.cpp9
-rw-r--r--src/qml/qml/qqmlincubator.cpp17
-rw-r--r--src/qml/qml/qqmlincubator_p.h5
-rw-r--r--src/qml/qml/qqmllocale.cpp485
-rw-r--r--src/qml/qml/qqmllocale_p.h82
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp15
-rw-r--r--src/qml/qml/qqmlobjectcreator_p.h1
-rw-r--r--src/qml/qml/qqmltypeloader.cpp50
-rw-r--r--src/qml/qml/qqmltypeloader_p.h2
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper.cpp12
-rw-r--r--src/qml/qml/qqmlvaluetypewrapper_p.h2
-rw-r--r--src/qml/qml/qqmlvme.cpp12
-rw-r--r--src/qml/qml/qqmlvme_p.h1
-rw-r--r--src/qml/qml/qqmlxmlhttprequest.cpp496
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp865
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions_p.h118
-rw-r--r--src/qml/qml/v8/qv4domerrors_p.h5
-rw-r--r--src/qml/types/qqmldelegatemodel.cpp79
-rw-r--r--src/qml/types/qqmldelegatemodel_p_p.h6
-rw-r--r--src/qml/types/qquickworkerscript.cpp13
-rw-r--r--src/quick/items/context2d/qquickcontext2d.cpp1297
-rw-r--r--src/quick/items/qquickmousearea.cpp3
-rw-r--r--src/quick/util/qquickimageprovider.cpp2
-rw-r--r--src/quick/util/qquickpixmapcache.cpp9
-rw-r--r--src/quick/util/qquickpixmapcache_p.h4
87 files changed, 4887 insertions, 4232 deletions
diff --git a/src/plugins/scenegraph/openvg/openvg.pro b/src/plugins/scenegraph/openvg/openvg.pro
index 8a58796a05..6d5b190b37 100644
--- a/src/plugins/scenegraph/openvg/openvg.pro
+++ b/src/plugins/scenegraph/openvg/openvg.pro
@@ -10,6 +10,7 @@ QMAKE_TARGET_PRODUCT = "Qt Quick OpenVG Renderer (Qt $$QT_VERSION)"
QMAKE_TARGET_DESCRIPTION = "Quick OpenVG Renderer for Qt."
QMAKE_USE += openvg
+CONFIG += egl
OTHER_FILES += $$PWD/openvg.json
diff --git a/src/plugins/scenegraph/openvg/qopenvgoffscreensurface.cpp b/src/plugins/scenegraph/openvg/qopenvgoffscreensurface.cpp
index 80af227fb4..1f2709e06c 100644
--- a/src/plugins/scenegraph/openvg/qopenvgoffscreensurface.cpp
+++ b/src/plugins/scenegraph/openvg/qopenvgoffscreensurface.cpp
@@ -37,10 +37,11 @@
**
****************************************************************************/
+#include <QDebug>
#include "qopenvgoffscreensurface.h"
#include <QtGui/QImage>
-#include <QDebug>
+
QT_BEGIN_NAMESPACE
@@ -71,7 +72,7 @@ QOpenVGOffscreenSurface::QOpenVGOffscreenSurface(const QSize &size)
m_renderTarget = eglCreatePbufferFromClientBuffer(m_display,
EGL_OPENVG_IMAGE,
- (EGLClientBuffer)m_image,
+ reinterpret_cast<EGLClientBuffer>(uintptr_t(m_image)),
pbufferConfig,
0);
if (m_renderTarget == EGL_NO_SURFACE)
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgcontext.cpp b/src/plugins/scenegraph/openvg/qsgopenvgcontext.cpp
index 22a80c62e8..41fce7c7fc 100644
--- a/src/plugins/scenegraph/openvg/qsgopenvgcontext.cpp
+++ b/src/plugins/scenegraph/openvg/qsgopenvgcontext.cpp
@@ -39,8 +39,6 @@
#include "qsgopenvgcontext_p.h"
#include "qsgopenvgrenderer_p.h"
-#include "qsgopenvginternalrectanglenode.h"
-#include "qsgopenvginternalimagenode.h"
#include "qsgopenvgpublicnodes.h"
#include "qsgopenvgtexture.h"
#include "qsgopenvglayer.h"
@@ -52,6 +50,8 @@
#include "qopenvgcontext_p.h"
#include <private/qsgrenderer_p.h>
+#include "qsgopenvginternalrectanglenode.h"
+#include "qsgopenvginternalimagenode.h"
// polish, animations, sync, render and swap in the render loop
Q_LOGGING_CATEGORY(QSG_OPENVG_LOG_TIME_RENDERLOOP, "qt.scenegraph.time.renderloop")
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.cpp b/src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.cpp
index 1afc5ea7ca..e45b79706b 100644
--- a/src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.cpp
+++ b/src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.cpp
@@ -39,6 +39,8 @@
#include "qsgopenvgpublicnodes.h"
#include "qsgopenvghelpers.h"
+#include <VG/openvg.h>
+#include <QtGui/QPixmap>
QT_BEGIN_NAMESPACE
@@ -66,6 +68,11 @@ void QSGOpenVGRectangleNode::setRect(const QRectF &rect)
markDirty(DirtyMaterial);
}
+QRectF QSGOpenVGRectangleNode::rect() const
+{
+ return m_rect;
+}
+
void QSGOpenVGRectangleNode::setColor(const QColor &color)
{
m_color = color;
@@ -73,6 +80,11 @@ void QSGOpenVGRectangleNode::setColor(const QColor &color)
markDirty(DirtyMaterial);
}
+QColor QSGOpenVGRectangleNode::color() const
+{
+ return m_color;
+}
+
void QSGOpenVGRectangleNode::setTransform(const QOpenVGMatrix &transform)
{
// if there transform matrix is not affine, regenerate the path
@@ -177,12 +189,58 @@ QSGOpenVGImageNode::~QSGOpenVGImageNode()
}
}
+void QSGOpenVGImageNode::setRect(const QRectF &rect)
+{
+ m_rect = rect;
+ markDirty(DirtyMaterial);
+}
+
+QRectF QSGOpenVGImageNode::rect() const
+{
+ return m_rect;
+}
+
+void QSGOpenVGImageNode::setSourceRect(const QRectF &r)
+{
+ m_sourceRect = r;
+}
+
+QRectF QSGOpenVGImageNode::sourceRect() const
+{
+ return m_sourceRect;
+}
+
void QSGOpenVGImageNode::setTexture(QSGTexture *texture)
{
m_texture = texture;
markDirty(DirtyMaterial);
}
+QSGTexture *QSGOpenVGImageNode::texture() const
+{
+ return m_texture;
+}
+
+void QSGOpenVGImageNode::setFiltering(QSGTexture::Filtering filtering)
+{
+ m_filtering = filtering;
+ markDirty(DirtyMaterial);
+}
+
+QSGTexture::Filtering QSGOpenVGImageNode::filtering() const
+{
+ return m_filtering;
+}
+
+void QSGOpenVGImageNode::setMipmapFiltering(QSGTexture::Filtering)
+{
+}
+
+QSGTexture::Filtering QSGOpenVGImageNode::mipmapFiltering() const
+{
+ return QSGTexture::None;
+}
+
void QSGOpenVGImageNode::setTextureCoordinatesTransform(QSGImageNode::TextureCoordinatesTransformMode transformNode)
{
if (m_transformMode == transformNode)
@@ -191,6 +249,21 @@ void QSGOpenVGImageNode::setTextureCoordinatesTransform(QSGImageNode::TextureCoo
markDirty(DirtyGeometry);
}
+QSGImageNode::TextureCoordinatesTransformMode QSGOpenVGImageNode::textureCoordinatesTransform() const
+{
+ return m_transformMode;
+}
+
+void QSGOpenVGImageNode::setOwnsTexture(bool owns)
+{
+ m_owns = owns;
+}
+
+bool QSGOpenVGImageNode::ownsTexture() const
+{
+ return m_owns;
+}
+
void QSGOpenVGImageNode::render()
{
if (!m_texture) {
diff --git a/src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.h b/src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.h
index 34c8e50615..8e12c27824 100644
--- a/src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.h
+++ b/src/plugins/scenegraph/openvg/qsgopenvgpublicnodes.h
@@ -44,10 +44,6 @@
#include <QtQuick/qsgimagenode.h>
#include <QtQuick/qsgninepatchnode.h>
-#include <QtGui/QPixmap>
-
-#include <VG/openvg.h>
-
#include "qsgopenvgrenderable.h"
QT_BEGIN_NAMESPACE
@@ -59,10 +55,10 @@ public:
~QSGOpenVGRectangleNode();
void setRect(const QRectF &rect) override;
- QRectF rect() const override { return m_rect; }
+ QRectF rect() const override;
void setColor(const QColor &color) override;
- QColor color() const override { return m_color; }
+ QColor color() const override;
void setTransform(const QOpenVGMatrix &transform) override;
@@ -86,26 +82,26 @@ public:
QSGOpenVGImageNode();
~QSGOpenVGImageNode();
- void setRect(const QRectF &rect) override { m_rect = rect; markDirty(DirtyMaterial); }
- QRectF rect() const override { return m_rect; }
+ void setRect(const QRectF &rect) override;
+ QRectF rect() const override;
- void setSourceRect(const QRectF &r) override { m_sourceRect = r; }
- QRectF sourceRect() const override { return m_sourceRect; }
+ void setSourceRect(const QRectF &r) override;
+ QRectF sourceRect() const override;
void setTexture(QSGTexture *texture) override;
- QSGTexture *texture() const override { return m_texture; }
+ QSGTexture *texture() const override;
- void setFiltering(QSGTexture::Filtering filtering) override { m_filtering = filtering; markDirty(DirtyMaterial); }
- QSGTexture::Filtering filtering() const override { return m_filtering; }
+ void setFiltering(QSGTexture::Filtering filtering) override;
+ QSGTexture::Filtering filtering() const override;
- void setMipmapFiltering(QSGTexture::Filtering) override { }
- QSGTexture::Filtering mipmapFiltering() const override { return QSGTexture::None; }
+ void setMipmapFiltering(QSGTexture::Filtering) override;
+ QSGTexture::Filtering mipmapFiltering() const override;
void setTextureCoordinatesTransform(TextureCoordinatesTransformMode transformNode) override;
- TextureCoordinatesTransformMode textureCoordinatesTransform() const override { return m_transformMode; }
+ TextureCoordinatesTransformMode textureCoordinatesTransform() const override;
- void setOwnsTexture(bool owns) override { m_owns = owns; }
- bool ownsTexture() const override { return m_owns; }
+ void setOwnsTexture(bool owns) override;
+ bool ownsTexture() const override;
void render() override;
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index e0def1021b..46c27fc735 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -526,21 +526,21 @@ IR::Expr *Codegen::subscript(IR::Expr *base, IR::Expr *index)
if (hasError)
return 0;
- if (! base->asTemp() || base->asArgLocal()) {
+ if (! base->asTemp() && !base->asArgLocal()) {
const unsigned t = _block->newTemp();
move(_block->TEMP(t), base);
base = _block->TEMP(t);
}
- if (! index->asTemp() || index->asArgLocal()) {
+ if (! index->asTemp() && !index->asArgLocal() && !index->asConst()) {
const unsigned t = _block->newTemp();
move(_block->TEMP(t), index);
index = _block->TEMP(t);
}
Q_ASSERT(base->asTemp() || base->asArgLocal());
- Q_ASSERT(index->asTemp() || index->asArgLocal());
- return _block->SUBSCRIPT(base->asTemp(), index->asTemp());
+ Q_ASSERT(index->asTemp() || index->asArgLocal() || index->asConst());
+ return _block->SUBSCRIPT(base, index);
}
IR::Expr *Codegen::argument(IR::Expr *expr)
diff --git a/src/qml/jsruntime/qv4arraybuffer.cpp b/src/qml/jsruntime/qv4arraybuffer.cpp
index 23075aa78c..ffe9aa846f 100644
--- a/src/qml/jsruntime/qv4arraybuffer.cpp
+++ b/src/qml/jsruntime/qv4arraybuffer.cpp
@@ -81,16 +81,19 @@ void ArrayBufferCtor::call(const Managed *that, Scope &scope, CallData *callData
construct(that, scope, callData);
}
-ReturnedValue ArrayBufferCtor::method_isView(CallContext *ctx)
+void ArrayBufferCtor::method_isView(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- 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(false);
+ QV4::Scoped<TypedArray> a(scope, callData->argument(0));
+ if (!!a) {
+ scope.result = Encode(true);
+ return;
+ }
+ QV4::Scoped<DataView> v(scope, callData->argument(0));
+ if (!!v) {
+ scope.result = Encode(true);
+ return;
+ }
+ scope.result = Encode(false);
}
@@ -160,54 +163,48 @@ void ArrayBufferPrototype::init(ExecutionEngine *engine, Object *ctor)
defineDefaultProperty(QStringLiteral("toString"), method_toString, 0);
}
-ReturnedValue ArrayBufferPrototype::method_get_byteLength(CallContext *ctx)
+void ArrayBufferPrototype::method_get_byteLength(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<ArrayBuffer> v(scope, ctx->thisObject());
+ Scoped<ArrayBuffer> v(scope, callData->thisObject);
if (!v)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
- return Encode(v->d()->data->size);
+ scope.result = Encode(v->d()->data->size);
}
-ReturnedValue ArrayBufferPrototype::method_slice(CallContext *ctx)
+void ArrayBufferPrototype::method_slice(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<ArrayBuffer> a(scope, ctx->thisObject());
+ Scoped<ArrayBuffer> a(scope, callData->thisObject);
if (!a)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
- double start = ctx->argc() > 0 ? ctx->args()[0].toInteger() : 0;
- double end = (ctx->argc() < 2 || ctx->args()[1].isUndefined()) ?
- a->d()->data->size : ctx->args()[1].toInteger();
- if (scope.engine->hasException)
- return Encode::undefined();
+ double start = callData->argc > 0 ? callData->args[0].toInteger() : 0;
+ double end = (callData->argc < 2 || callData->args[1].isUndefined()) ?
+ a->d()->data->size : callData->args[1].toInteger();
+ CHECK_EXCEPTION();
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);
ScopedFunctionObject constructor(scope, a->get(scope.engine->id_constructor()));
if (!constructor)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
- ScopedCallData callData(scope, 1);
+ ScopedCallData cData(scope, 1);
double newLen = qMax(final - first, 0.);
- callData->args[0] = QV4::Encode(newLen);
- constructor->construct(scope, callData);
- QV4::Scoped<ArrayBuffer> newBuffer(scope, scope.result.asReturnedValue());
+ cData->args[0] = QV4::Encode(newLen);
+ constructor->construct(scope, cData);
+ QV4::Scoped<ArrayBuffer> newBuffer(scope, scope.result);
if (!newBuffer || newBuffer->d()->data->size < (int)newLen)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
memcpy(newBuffer->d()->data->data(), a->d()->data->data() + (uint)first, newLen);
-
- return newBuffer.asReturnedValue();
}
-ReturnedValue ArrayBufferPrototype::method_toString(CallContext *ctx)
+void ArrayBufferPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<ArrayBuffer> a(scope, ctx->thisObject());
+ Scoped<ArrayBuffer> a(scope, callData->thisObject);
if (!a)
- return Encode::undefined();
- return Encode(ctx->engine()->newString(QString::fromUtf8(a->asByteArray())));
+ RETURN_UNDEFINED();
+ scope.result = scope.engine->newString(QString::fromUtf8(a->asByteArray()));
}
diff --git a/src/qml/jsruntime/qv4arraybuffer_p.h b/src/qml/jsruntime/qv4arraybuffer_p.h
index bc56d1ea31..4f7926d3dc 100644
--- a/src/qml/jsruntime/qv4arraybuffer_p.h
+++ b/src/qml/jsruntime/qv4arraybuffer_p.h
@@ -81,7 +81,7 @@ struct ArrayBufferCtor: FunctionObject
static void construct(const Managed *m, Scope &scope, CallData *callData);
static void call(const Managed *that, Scope &scope, CallData *callData);
- static ReturnedValue method_isView(CallContext *ctx);
+ static void method_isView(const BuiltinFunction *, Scope &scope, CallData *callData);
};
@@ -104,9 +104,9 @@ struct ArrayBufferPrototype: Object
{
void init(ExecutionEngine *engine, Object *ctor);
- static ReturnedValue method_get_byteLength(CallContext *ctx);
- static ReturnedValue method_slice(CallContext *ctx);
- static ReturnedValue method_toString(CallContext *ctx);
+ static void method_get_byteLength(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_slice(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
};
diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp
index bfeb3d4699..d8a7de5466 100644
--- a/src/qml/jsruntime/qv4arraydata.cpp
+++ b/src/qml/jsruntime/qv4arraydata.cpp
@@ -237,8 +237,14 @@ void ArrayData::ensureAttributes(Object *o)
void SimpleArrayData::markObjects(Heap::Base *d, ExecutionEngine *e)
{
Heap::SimpleArrayData *dd = static_cast<Heap::SimpleArrayData *>(d);
- for (uint i = 0; i < dd->len; ++i)
- dd->arrayData[dd->mappedIndex(i)].mark(e);
+ uint end = dd->offset + dd->len;
+ if (end > dd->alloc) {
+ for (uint i = 0; i < end - dd->alloc; ++i)
+ dd->arrayData[i].mark(e);
+ end = dd->alloc;
+ }
+ for (uint i = dd->offset; i < end; ++i)
+ dd->arrayData[i].mark(e);
}
ReturnedValue SimpleArrayData::get(const Heap::ArrayData *d, uint index)
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp
index 20ba11fd75..759354f4e2 100644
--- a/src/qml/jsruntime/qv4arrayobject.cpp
+++ b/src/qml/jsruntime/qv4arrayobject.cpp
@@ -44,6 +44,7 @@
#include "qv4argumentsobject_p.h"
#include "qv4runtime_p.h"
#include "qv4string_p.h"
+#include <QtCore/qscopedvaluerollback.h>
using namespace QV4;
@@ -118,42 +119,40 @@ void ArrayPrototype::init(ExecutionEngine *engine, Object *ctor)
defineDefaultProperty(QStringLiteral("reduceRight"), method_reduceRight, 1);
}
-ReturnedValue ArrayPrototype::method_isArray(CallContext *ctx)
+void ArrayPrototype::method_isArray(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- bool isArray = ctx->argc() && ctx->args()[0].as<ArrayObject>();
- return Encode(isArray);
+ bool isArray = callData->argc && callData->args[0].as<ArrayObject>();
+ scope.result = Encode(isArray);
}
-ReturnedValue ArrayPrototype::method_toString(CallContext *ctx)
+void ArrayPrototype::method_toString(const BuiltinFunction *builtin, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject o(scope, ctx->thisObject(), ScopedObject::Convert);
- if (ctx->d()->engine->hasException)
- return Encode::undefined();
- ScopedString s(scope, ctx->d()->engine->newString(QStringLiteral("join")));
+ ScopedObject o(scope, callData->thisObject, ScopedObject::Convert);
+ CHECK_EXCEPTION();
+ ScopedString s(scope, scope.engine->newString(QStringLiteral("join")));
ScopedFunctionObject f(scope, o->get(s));
if (!!f) {
ScopedCallData d(scope, 0);
- d->thisObject = ctx->thisObject();
+ d->thisObject = callData->thisObject;
f->call(scope, d);
- return scope.result.asReturnedValue();
+ return;
}
- return ObjectPrototype::method_toString(ctx);
+ ObjectPrototype::method_toString(builtin, scope, callData);
}
-ReturnedValue ArrayPrototype::method_toLocaleString(CallContext *ctx)
+void ArrayPrototype::method_toLocaleString(const BuiltinFunction *builtin, Scope &scope, CallData *callData)
{
- return method_toString(ctx);
+ return method_toString(builtin, scope, callData);
}
-ReturnedValue ArrayPrototype::method_concat(CallContext *ctx)
+void ArrayPrototype::method_concat(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject result(scope, ctx->d()->engine->newArrayObject());
-
- ScopedObject thisObject(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject thisObject(scope, callData->thisObject.toObject(scope.engine));
if (!thisObject)
- return Encode::undefined();
+ RETURN_UNDEFINED();
+
+ ScopedArrayObject result(scope, scope.engine->newArrayObject());
+
if (thisObject->isArrayObject()) {
result->copyArrayData(thisObject);
} else {
@@ -163,9 +162,9 @@ ReturnedValue ArrayPrototype::method_concat(CallContext *ctx)
ScopedArrayObject elt(scope);
ScopedObject eltAsObj(scope);
ScopedValue entry(scope);
- for (int i = 0; i < ctx->argc(); ++i) {
- eltAsObj = ctx->args()[i];
- elt = ctx->args()[i];
+ for (int i = 0; i < callData->argc; ++i) {
+ eltAsObj = callData->args[i];
+ elt = callData->args[i];
if (elt) {
uint n = elt->getLength();
uint newLen = ArrayData::append(result, elt, n);
@@ -177,95 +176,90 @@ ReturnedValue ArrayPrototype::method_concat(CallContext *ctx)
result->putIndexed(startIndex + i, entry);
}
} else {
- result->arraySet(result->getLength(), ctx->args()[i]);
+ result->arraySet(result->getLength(), callData->args[i]);
}
}
- return result.asReturnedValue();
+ scope.result = result;
}
-ReturnedValue ArrayPrototype::method_find(CallContext *ctx)
+void ArrayPrototype::method_find(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
uint len = instance->getLength();
- ScopedFunctionObject callback(scope, ctx->argument(0));
+ ScopedFunctionObject callback(scope, callData->argument(0));
if (!callback)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- ScopedCallData callData(scope, 3);
- callData->thisObject = ctx->argument(1);
- callData->args[2] = instance;
+ ScopedCallData cData(scope, 3);
+ cData->thisObject = callData->argument(1);
+ cData->args[2] = instance;
ScopedValue v(scope);
for (uint k = 0; k < len; ++k) {
v = instance->getIndexed(k);
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
- callData->args[0] = v;
- callData->args[1] = Primitive::fromDouble(k);
- callback->call(scope, callData);
+ cData->args[0] = v;
+ cData->args[1] = Primitive::fromDouble(k);
+ callback->call(scope, cData);
- if (scope.hasException())
- return Encode::undefined();
- else if (scope.result.toBoolean())
- return v->asReturnedValue();
+ CHECK_EXCEPTION();
+ if (scope.result.toBoolean())
+ RETURN_RESULT(v);
}
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
-ReturnedValue ArrayPrototype::method_findIndex(CallContext *ctx)
+void ArrayPrototype::method_findIndex(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
uint len = instance->getLength();
- ScopedFunctionObject callback(scope, ctx->argument(0));
+ ScopedFunctionObject callback(scope, callData->argument(0));
if (!callback)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- ScopedCallData callData(scope, 3);
- callData->thisObject = ctx->argument(1);
- callData->args[2] = instance;
+ ScopedCallData cData(scope, 3);
+ cData->thisObject = callData->argument(1);
+ cData->args[2] = instance;
ScopedValue v(scope);
for (uint k = 0; k < len; ++k) {
v = instance->getIndexed(k);
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
- callData->args[0] = v;
- callData->args[1] = Primitive::fromDouble(k);
- callback->call(scope, callData);
+ cData->args[0] = v;
+ cData->args[1] = Primitive::fromDouble(k);
+ callback->call(scope, cData);
- if (scope.hasException())
- return Encode::undefined();
- else if (scope.result.toBoolean())
- return Encode(k);
+ CHECK_EXCEPTION();
+ if (scope.result.toBoolean())
+ RETURN_RESULT(Encode(k));
}
- return Encode(-1);
+ RETURN_RESULT(Encode(-1));
}
-ReturnedValue ArrayPrototype::method_join(CallContext *ctx)
+void ArrayPrototype::method_join(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedValue arg(scope, ctx->argument(0));
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedValue arg(scope, callData->argument(0));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
- if (!instance)
- return ctx->d()->engine->newString()->asReturnedValue();
+ if (!instance) {
+ scope.result = scope.engine->newString();
+ return;
+ }
QString r4;
if (arg->isUndefined())
@@ -273,11 +267,13 @@ ReturnedValue ArrayPrototype::method_join(CallContext *ctx)
else
r4 = arg->toQString();
- ScopedValue length(scope, instance->get(ctx->d()->engine->id_length()));
+ ScopedValue length(scope, instance->get(scope.engine->id_length()));
const quint32 r2 = length->isUndefined() ? 0 : length->toUInt32();
- if (!r2)
- return ctx->d()->engine->newString()->asReturnedValue();
+ if (!r2) {
+ scope.result = scope.engine->newString();
+ return;
+ }
QString R;
@@ -289,8 +285,7 @@ ReturnedValue ArrayPrototype::method_join(CallContext *ctx)
R += r4;
e = a->getIndexed(i);
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
if (!e->isNullOrUndefined())
R += e->toQString();
}
@@ -298,7 +293,7 @@ ReturnedValue ArrayPrototype::method_join(CallContext *ctx)
//
// crazy!
//
- ScopedString name(scope, ctx->d()->engine->newString(QStringLiteral("0")));
+ ScopedString name(scope, scope.engine->newString(QStringLiteral("0")));
ScopedValue r6(scope, instance->get(name));
if (!r6->isNullOrUndefined())
R = r6->toQString();
@@ -309,99 +304,98 @@ ReturnedValue ArrayPrototype::method_join(CallContext *ctx)
name = Primitive::fromDouble(k).toString(scope.engine);
r12 = instance->get(name);
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
if (!r12->isNullOrUndefined())
R += r12->toQString();
}
}
- return ctx->d()->engine->newString(R)->asReturnedValue();
+ scope.result = scope.engine->newString(R);
}
-ReturnedValue ArrayPrototype::method_pop(CallContext *ctx)
+void ArrayPrototype::method_pop(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
+
uint len = instance->getLength();
if (!len) {
if (!instance->isArrayObject())
- instance->put(ctx->d()->engine->id_length(), ScopedValue(scope, Primitive::fromInt32(0)));
- return Encode::undefined();
+ instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromInt32(0)));
+ RETURN_UNDEFINED();
}
ScopedValue result(scope, instance->getIndexed(len - 1));
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
instance->deleteIndexedProperty(len - 1);
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
+
if (instance->isArrayObject())
instance->setArrayLength(len - 1);
else
- instance->put(ctx->d()->engine->id_length(), ScopedValue(scope, Primitive::fromDouble(len - 1)));
- return result->asReturnedValue();
+ instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromDouble(len - 1)));
+ scope.result = result;
}
-ReturnedValue ArrayPrototype::method_push(CallContext *ctx)
+void ArrayPrototype::method_push(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
instance->arrayCreate();
Q_ASSERT(instance->arrayData());
uint len = instance->getLength();
- if (len + ctx->argc() < len) {
+ if (len + callData->argc < len) {
// ughh...
double l = len;
ScopedString s(scope);
- for (int i = 0; i < ctx->argc(); ++i) {
+ for (int i = 0; i < callData->argc; ++i) {
s = Primitive::fromDouble(l + i).toString(scope.engine);
- instance->put(s, ctx->args()[i]);
+ instance->put(s, callData->args[i]);
}
- double newLen = l + ctx->argc();
+ double newLen = l + callData->argc;
if (!instance->isArrayObject())
- instance->put(ctx->d()->engine->id_length(), ScopedValue(scope, Primitive::fromDouble(newLen)));
+ instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromDouble(newLen)));
else {
- ScopedString str(scope, ctx->d()->engine->newString(QStringLiteral("Array.prototype.push: Overflow")));
- return ctx->engine()->throwRangeError(str);
+ ScopedString str(scope, scope.engine->newString(QStringLiteral("Array.prototype.push: Overflow")));
+ scope.result = scope.engine->throwRangeError(str);
+ return;
}
- return Encode(newLen);
+ scope.result = Encode(newLen);
+ return;
}
- if (!ctx->argc())
+ if (!callData->argc)
;
else if (!instance->protoHasArray() && instance->arrayData()->length() <= len && instance->arrayData()->type == Heap::ArrayData::Simple) {
- instance->arrayData()->vtable()->putArray(instance, len, ctx->args(), ctx->argc());
+ instance->arrayData()->vtable()->putArray(instance, len, callData->args, callData->argc);
len = instance->arrayData()->length();
} else {
- for (int i = 0; i < ctx->argc(); ++i)
- instance->putIndexed(len + i, ctx->args()[i]);
- len += ctx->argc();
+ for (int i = 0; i < callData->argc; ++i)
+ instance->putIndexed(len + i, callData->args[i]);
+ len += callData->argc;
}
if (instance->isArrayObject())
instance->setArrayLengthUnchecked(len);
else
- instance->put(ctx->d()->engine->id_length(), ScopedValue(scope, Primitive::fromDouble(len)));
+ instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromDouble(len)));
- return Encode(len);
+ scope.result = Encode(len);
}
-ReturnedValue ArrayPrototype::method_reverse(CallContext *ctx)
+void ArrayPrototype::method_reverse(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
+
uint length = instance->getLength();
int lo = 0, hi = length - 1;
@@ -412,28 +406,25 @@ ReturnedValue ArrayPrototype::method_reverse(CallContext *ctx)
bool loExists, hiExists;
lval = instance->getIndexed(lo, &loExists);
hval = instance->getIndexed(hi, &hiExists);
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
if (hiExists)
instance->putIndexed(lo, hval);
else
instance->deleteIndexedProperty(lo);
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
if (loExists)
instance->putIndexed(hi, lval);
else
instance->deleteIndexedProperty(hi);
}
- return instance.asReturnedValue();
+ scope.result = instance;
}
-ReturnedValue ArrayPrototype::method_shift(CallContext *ctx)
+void ArrayPrototype::method_shift(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
instance->arrayCreate();
Q_ASSERT(instance->arrayData());
@@ -442,54 +433,46 @@ ReturnedValue ArrayPrototype::method_shift(CallContext *ctx)
if (!len) {
if (!instance->isArrayObject())
- instance->put(ctx->d()->engine->id_length(), ScopedValue(scope, Primitive::fromInt32(0)));
- return Encode::undefined();
+ instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromInt32(0)));
+ RETURN_UNDEFINED();
}
- ScopedValue result(scope);
-
if (!instance->protoHasArray() && !instance->arrayData()->attrs && instance->arrayData()->length() <= len && instance->arrayData()->type != Heap::ArrayData::Custom) {
- result = instance->arrayData()->vtable()->pop_front(instance);
+ scope.result = instance->arrayData()->vtable()->pop_front(instance);
} else {
- result = instance->getIndexed(0);
- if (scope.hasException())
- return Encode::undefined();
+ scope.result = instance->getIndexed(0);
+ CHECK_EXCEPTION();
ScopedValue v(scope);
// do it the slow way
for (uint k = 1; k < len; ++k) {
bool exists;
v = instance->getIndexed(k, &exists);
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
if (exists)
instance->putIndexed(k - 1, v);
else
instance->deleteIndexedProperty(k - 1);
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
}
instance->deleteIndexedProperty(len - 1);
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
}
if (instance->isArrayObject())
instance->setArrayLengthUnchecked(len - 1);
else
- instance->put(ctx->d()->engine->id_length(), ScopedValue(scope, Primitive::fromDouble(len - 1)));
- return result->asReturnedValue();
+ instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromDouble(len - 1)));
}
-ReturnedValue ArrayPrototype::method_slice(CallContext *ctx)
+void ArrayPrototype::method_slice(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject o(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject o(scope, callData->thisObject.toObject(scope.engine));
if (!o)
- return Encode::undefined();
+ RETURN_UNDEFINED();
- ScopedArrayObject result(scope, ctx->d()->engine->newArrayObject());
+ ScopedArrayObject result(scope, scope.engine->newArrayObject());
uint len = o->getLength();
- double s = ScopedValue(scope, ctx->argument(0))->toInteger();
+ double s = ScopedValue(scope, callData->argument(0))->toInteger();
uint start;
if (s < 0)
start = (uint)qMax(len + s, 0.);
@@ -498,8 +481,8 @@ ReturnedValue ArrayPrototype::method_slice(CallContext *ctx)
else
start = (uint) s;
uint end = len;
- if (ctx->argc() > 1 && !ctx->args()[1].isUndefined()) {
- double e = ctx->args()[1].toInteger();
+ if (callData->argc > 1 && !callData->args[1].isUndefined()) {
+ double e = callData->args[1].toInteger();
if (e < 0)
end = (uint)qMax(len + e, 0.);
else if (e > len)
@@ -513,115 +496,107 @@ ReturnedValue ArrayPrototype::method_slice(CallContext *ctx)
for (uint i = start; i < end; ++i) {
bool exists;
v = o->getIndexed(i, &exists);
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
if (exists)
result->arraySet(n, v);
++n;
}
- return result.asReturnedValue();
+ scope.result = result;
}
-ReturnedValue ArrayPrototype::method_sort(CallContext *ctx)
+void ArrayPrototype::method_sort(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
uint len = instance->getLength();
- ScopedValue comparefn(scope, ctx->argument(0));
+ ScopedValue comparefn(scope, callData->argument(0));
ArrayData::sort(scope.engine, instance, comparefn, len);
- return ctx->thisObject().asReturnedValue();
+ scope.result = callData->thisObject;
}
-ReturnedValue ArrayPrototype::method_splice(CallContext *ctx)
+void ArrayPrototype::method_splice(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
+
uint len = instance->getLength();
- ScopedArrayObject newArray(scope, ctx->d()->engine->newArrayObject());
+ ScopedArrayObject newArray(scope, scope.engine->newArrayObject());
- double rs = ScopedValue(scope, ctx->argument(0))->toInteger();
+ double rs = ScopedValue(scope, callData->argument(0))->toInteger();
uint start;
if (rs < 0)
start = (uint) qMax(0., len + rs);
else
start = (uint) qMin(rs, (double)len);
- uint deleteCount = (uint)qMin(qMax(ScopedValue(scope, ctx->argument(1))->toInteger(), 0.), (double)(len - start));
+ uint deleteCount = (uint)qMin(qMax(ScopedValue(scope, callData->argument(1))->toInteger(), 0.), (double)(len - start));
newArray->arrayReserve(deleteCount);
ScopedValue v(scope);
for (uint i = 0; i < deleteCount; ++i) {
bool exists;
v = instance->getIndexed(start + i, &exists);
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
if (exists)
newArray->arrayPut(i, v);
}
newArray->setArrayLengthUnchecked(deleteCount);
- uint itemCount = ctx->argc() < 2 ? 0 : ctx->argc() - 2;
+ uint itemCount = callData->argc < 2 ? 0 : callData->argc - 2;
if (itemCount < deleteCount) {
for (uint k = start; k < len - deleteCount; ++k) {
bool exists;
v = instance->getIndexed(k + deleteCount, &exists);
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
if (exists)
instance->putIndexed(k + itemCount, v);
else
instance->deleteIndexedProperty(k + itemCount);
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
}
for (uint k = len; k > len - deleteCount + itemCount; --k) {
instance->deleteIndexedProperty(k - 1);
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
}
} else if (itemCount > deleteCount) {
uint k = len - deleteCount;
while (k > start) {
bool exists;
v = instance->getIndexed(k + deleteCount - 1, &exists);
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
if (exists)
instance->putIndexed(k + itemCount - 1, v);
else
instance->deleteIndexedProperty(k + itemCount - 1);
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
--k;
}
}
for (uint i = 0; i < itemCount; ++i) {
- instance->putIndexed(start + i, ctx->args()[i + 2]);
- if (scope.hasException())
- return Encode::undefined();
+ instance->putIndexed(start + i, callData->args[i + 2]);
+ CHECK_EXCEPTION();
}
- ctx->d()->strictMode = true;
- instance->put(ctx->d()->engine->id_length(), ScopedValue(scope, Primitive::fromDouble(len - deleteCount + itemCount)));
+ bool wasStrict = scope.engine->current->strictMode;
+ scope.engine->current->strictMode = true;
+ instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromDouble(len - deleteCount + itemCount)));
- return newArray.asReturnedValue();
+ scope.result = newArray;
+ scope.engine->current->strictMode = wasStrict;
}
-ReturnedValue ArrayPrototype::method_unshift(CallContext *ctx)
+void ArrayPrototype::method_unshift(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
instance->arrayCreate();
Q_ASSERT(instance->arrayData());
@@ -630,50 +605,52 @@ ReturnedValue ArrayPrototype::method_unshift(CallContext *ctx)
if (!instance->protoHasArray() && !instance->arrayData()->attrs && instance->arrayData()->length() <= len &&
instance->arrayData()->type != Heap::ArrayData::Custom) {
- instance->arrayData()->vtable()->push_front(instance, ctx->args(), ctx->argc());
+ instance->arrayData()->vtable()->push_front(instance, callData->args, callData->argc);
} else {
ScopedValue v(scope);
for (uint k = len; k > 0; --k) {
bool exists;
v = instance->getIndexed(k - 1, &exists);
if (exists)
- instance->putIndexed(k + ctx->argc() - 1, v);
+ instance->putIndexed(k + callData->argc - 1, v);
else
- instance->deleteIndexedProperty(k + ctx->argc() - 1);
+ instance->deleteIndexedProperty(k + callData->argc - 1);
}
- for (int i = 0; i < ctx->argc(); ++i)
- instance->putIndexed(i, ctx->args()[i]);
+ for (int i = 0; i < callData->argc; ++i)
+ instance->putIndexed(i, callData->args[i]);
}
- uint newLen = len + ctx->argc();
+ uint newLen = len + callData->argc;
if (instance->isArrayObject())
instance->setArrayLengthUnchecked(newLen);
else
- instance->put(ctx->d()->engine->id_length(), ScopedValue(scope, Primitive::fromDouble(newLen)));
+ instance->put(scope.engine->id_length(), ScopedValue(scope, Primitive::fromDouble(newLen)));
- return Encode(newLen);
+ scope.result = Encode(newLen);
}
-ReturnedValue ArrayPrototype::method_indexOf(CallContext *ctx)
+void ArrayPrototype::method_indexOf(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
-
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
+
uint len = instance->getLength();
- if (!len)
- return Encode(-1);
+ if (!len) {
+ scope.result = Encode(-1);
+ return;
+ }
- ScopedValue searchValue(scope, ctx->argument(0));
+ ScopedValue searchValue(scope, callData->argument(0));
uint fromIndex = 0;
- if (ctx->argc() >= 2) {
- double f = ctx->args()[1].toInteger();
- if (scope.hasException())
- return Encode::undefined();
- if (f >= len)
- return Encode(-1);
+ if (callData->argc >= 2) {
+ double f = callData->args[1].toInteger();
+ CHECK_EXCEPTION();
+ if (f >= len) {
+ scope.result = Encode(-1);
+ return;
+ }
if (f < 0)
f = qMax(len + f, 0.);
fromIndex = (uint) f;
@@ -684,10 +661,13 @@ ReturnedValue ArrayPrototype::method_indexOf(CallContext *ctx)
for (uint k = fromIndex; k < len; ++k) {
bool exists;
v = instance->getIndexed(k, &exists);
- if (exists && RuntimeHelpers::strictEqual(v, searchValue))
- return Encode(k);
+ if (exists && RuntimeHelpers::strictEqual(v, searchValue)) {
+ scope.result = Encode(k);
+ return;
+ }
}
- return Encode(-1);
+ scope.result = Encode(-1);
+ return;
}
ScopedValue value(scope);
@@ -698,13 +678,15 @@ ReturnedValue ArrayPrototype::method_indexOf(CallContext *ctx)
for (uint i = fromIndex; i < len; ++i) {
bool exists;
value = instance->getIndexed(i, &exists);
- if (scope.hasException())
- return Encode::undefined();
- if (exists && RuntimeHelpers::strictEqual(value, searchValue))
- return Encode(i);
+ CHECK_EXCEPTION();
+ if (exists && RuntimeHelpers::strictEqual(value, searchValue)) {
+ scope.result = Encode(i);
+ return;
+ }
}
} else if (!instance->arrayData()) {
- return Encode(-1);
+ scope.result = Encode(-1);
+ return;
} else {
Q_ASSERT(instance->arrayType() == Heap::ArrayData::Simple || instance->arrayType() == Heap::ArrayData::Complex);
Heap::SimpleArrayData *sa = instance->d()->arrayData.cast<Heap::SimpleArrayData>();
@@ -713,45 +695,48 @@ ReturnedValue ArrayPrototype::method_indexOf(CallContext *ctx)
uint idx = fromIndex;
while (idx < len) {
value = sa->data(idx);
- if (scope.hasException())
- return Encode::undefined();
- if (RuntimeHelpers::strictEqual(value, searchValue))
- return Encode(idx);
+ CHECK_EXCEPTION();
+ if (RuntimeHelpers::strictEqual(value, searchValue)) {
+ scope.result = Encode(idx);
+ return;
+ }
++idx;
}
}
- return Encode(-1);
+ scope.result = Encode(-1);
}
-ReturnedValue ArrayPrototype::method_lastIndexOf(CallContext *ctx)
+void ArrayPrototype::method_lastIndexOf(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
-
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
+
uint len = instance->getLength();
- if (!len)
- return Encode(-1);
+ if (!len) {
+ scope.result = Encode(-1);
+ return;
+ }
ScopedValue searchValue(scope);
uint fromIndex = len;
- if (ctx->argc() >= 1)
- searchValue = ctx->argument(0);
+ if (callData->argc >= 1)
+ searchValue = callData->argument(0);
else
searchValue = Primitive::undefinedValue();
- if (ctx->argc() >= 2) {
- double f = ctx->args()[1].toInteger();
- if (scope.hasException())
- return Encode::undefined();
+ if (callData->argc >= 2) {
+ double f = callData->args[1].toInteger();
+ CHECK_EXCEPTION();
if (f > 0)
f = qMin(f, (double)(len - 1));
else if (f < 0) {
f = len + f;
- if (f < 0)
- return Encode(-1);
+ if (f < 0) {
+ scope.result = Encode(-1);
+ return;
+ }
}
fromIndex = (uint) f + 1;
}
@@ -761,30 +746,30 @@ ReturnedValue ArrayPrototype::method_lastIndexOf(CallContext *ctx)
--k;
bool exists;
v = instance->getIndexed(k, &exists);
- if (scope.hasException())
- return Encode::undefined();
- if (exists && RuntimeHelpers::strictEqual(v, searchValue))
- return Encode(k);
+ CHECK_EXCEPTION();
+ if (exists && RuntimeHelpers::strictEqual(v, searchValue)) {
+ scope.result = Encode(k);
+ return;
+ }
}
- return Encode(-1);
+ scope.result = Encode(-1);
}
-ReturnedValue ArrayPrototype::method_every(CallContext *ctx)
+void ArrayPrototype::method_every(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
uint len = instance->getLength();
- ScopedFunctionObject callback(scope, ctx->argument(0));
+ ScopedFunctionObject callback(scope, callData->argument(0));
if (!callback)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- ScopedCallData callData(scope, 3);
- callData->args[2] = instance;
- callData->thisObject = ctx->argument(1);
+ ScopedCallData cData(scope, 3);
+ cData->args[2] = instance;
+ cData->thisObject = callData->argument(1);
ScopedValue v(scope);
bool ok = true;
@@ -794,30 +779,29 @@ ReturnedValue ArrayPrototype::method_every(CallContext *ctx)
if (!exists)
continue;
- callData->args[0] = v;
- callData->args[1] = Primitive::fromDouble(k);
- callback->call(scope, callData);
+ cData->args[0] = v;
+ cData->args[1] = Primitive::fromDouble(k);
+ callback->call(scope, cData);
ok = scope.result.toBoolean();
}
- return Encode(ok);
+ scope.result = Encode(ok);
}
-ReturnedValue ArrayPrototype::method_some(CallContext *ctx)
+void ArrayPrototype::method_some(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
uint len = instance->getLength();
- ScopedFunctionObject callback(scope, ctx->argument(0));
+ ScopedFunctionObject callback(scope, callData->argument(0));
if (!callback)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- ScopedCallData callData(scope, 3);
- callData->thisObject = ctx->argument(1);
- callData->args[2] = instance;
+ ScopedCallData cData(scope, 3);
+ cData->thisObject = callData->argument(1);
+ cData->args[2] = instance;
ScopedValue v(scope);
for (uint k = 0; k < len; ++k) {
@@ -826,31 +810,32 @@ ReturnedValue ArrayPrototype::method_some(CallContext *ctx)
if (!exists)
continue;
- callData->args[0] = v;
- callData->args[1] = Primitive::fromDouble(k);
- callback->call(scope, callData);
- if (scope.result.toBoolean())
- return Encode(true);
+ cData->args[0] = v;
+ cData->args[1] = Primitive::fromDouble(k);
+ callback->call(scope, cData);
+ if (scope.result.toBoolean()) {
+ scope.result = Encode(true);
+ return;
+ }
}
- return Encode(false);
+ scope.result = Encode(false);
}
-ReturnedValue ArrayPrototype::method_forEach(CallContext *ctx)
+void ArrayPrototype::method_forEach(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
uint len = instance->getLength();
- ScopedFunctionObject callback(scope, ctx->argument(0));
+ ScopedFunctionObject callback(scope, callData->argument(0));
if (!callback)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- ScopedCallData callData(scope, 3);
- callData->thisObject = ctx->argument(1);
- callData->args[2] = instance;
+ ScopedCallData cData(scope, 3);
+ cData->thisObject = callData->argument(1);
+ cData->args[2] = instance;
ScopedValue v(scope);
for (uint k = 0; k < len; ++k) {
@@ -859,33 +844,32 @@ ReturnedValue ArrayPrototype::method_forEach(CallContext *ctx)
if (!exists)
continue;
- callData->args[0] = v;
- callData->args[1] = Primitive::fromDouble(k);
- callback->call(scope, callData);
+ cData->args[0] = v;
+ cData->args[1] = Primitive::fromDouble(k);
+ callback->call(scope, cData);
}
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
-ReturnedValue ArrayPrototype::method_map(CallContext *ctx)
+void ArrayPrototype::method_map(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
uint len = instance->getLength();
- ScopedFunctionObject callback(scope, ctx->argument(0));
+ ScopedFunctionObject callback(scope, callData->argument(0));
if (!callback)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- ScopedArrayObject a(scope, ctx->d()->engine->newArrayObject());
+ ScopedArrayObject a(scope, scope.engine->newArrayObject());
a->arrayReserve(len);
a->setArrayLengthUnchecked(len);
- ScopedCallData callData(scope, 3);
- callData->thisObject = ctx->argument(1);
- callData->args[2] = instance;
+ ScopedCallData cData(scope, 3);
+ cData->thisObject = callData->argument(1);
+ cData->args[2] = instance;
ScopedValue v(scope);
for (uint k = 0; k < len; ++k) {
@@ -894,33 +878,32 @@ ReturnedValue ArrayPrototype::method_map(CallContext *ctx)
if (!exists)
continue;
- callData->args[0] = v;
- callData->args[1] = Primitive::fromDouble(k);
- callback->call(scope, callData);
+ cData->args[0] = v;
+ cData->args[1] = Primitive::fromDouble(k);
+ callback->call(scope, cData);
a->arraySet(k, scope.result);
}
- return a.asReturnedValue();
+ scope.result = a.asReturnedValue();
}
-ReturnedValue ArrayPrototype::method_filter(CallContext *ctx)
+void ArrayPrototype::method_filter(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
uint len = instance->getLength();
- ScopedFunctionObject callback(scope, ctx->argument(0));
+ ScopedFunctionObject callback(scope, callData->argument(0));
if (!callback)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- ScopedArrayObject a(scope, ctx->d()->engine->newArrayObject());
+ ScopedArrayObject a(scope, scope.engine->newArrayObject());
a->arrayReserve(len);
- ScopedCallData callData(scope, 3);
- callData->thisObject = ctx->argument(1);
- callData->args[2] = instance;
+ ScopedCallData cData(scope, 3);
+ cData->thisObject = callData->argument(1);
+ cData->args[2] = instance;
ScopedValue v(scope);
@@ -931,35 +914,34 @@ ReturnedValue ArrayPrototype::method_filter(CallContext *ctx)
if (!exists)
continue;
- callData->args[0] = v;
- callData->args[1] = Primitive::fromDouble(k);
- callback->call(scope, callData);
+ cData->args[0] = v;
+ cData->args[1] = Primitive::fromDouble(k);
+ callback->call(scope, cData);
if (scope.result.toBoolean()) {
a->arraySet(to, v);
++to;
}
}
- return a.asReturnedValue();
+ scope.result = a.asReturnedValue();
}
-ReturnedValue ArrayPrototype::method_reduce(CallContext *ctx)
+void ArrayPrototype::method_reduce(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
uint len = instance->getLength();
- ScopedFunctionObject callback(scope, ctx->argument(0));
+ ScopedFunctionObject callback(scope, callData->argument(0));
if (!callback)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
uint k = 0;
ScopedValue v(scope);
- if (ctx->argc() > 1) {
- scope.result = ctx->argument(1);
+ if (callData->argc > 1) {
+ scope.result = callData->argument(1);
} else {
bool kPresent = false;
while (k < len && !kPresent) {
@@ -969,51 +951,50 @@ ReturnedValue ArrayPrototype::method_reduce(CallContext *ctx)
++k;
}
if (!kPresent)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
}
- ScopedCallData callData(scope, 4);
- callData->thisObject = Primitive::undefinedValue();
- callData->args[0] = scope.result;
- callData->args[3] = instance;
+ ScopedCallData cData(scope, 4);
+ cData->thisObject = Primitive::undefinedValue();
+ cData->args[0] = scope.result;
+ cData->args[3] = instance;
while (k < len) {
bool kPresent;
v = instance->getIndexed(k, &kPresent);
if (kPresent) {
- callData->args[0] = scope.result;
- callData->args[1] = v;
- callData->args[2] = Primitive::fromDouble(k);
- callback->call(scope, callData);
+ cData->args[0] = scope.result;
+ cData->args[1] = v;
+ cData->args[2] = Primitive::fromDouble(k);
+ callback->call(scope, cData);
}
++k;
}
- return scope.result.asReturnedValue();
}
-ReturnedValue ArrayPrototype::method_reduceRight(CallContext *ctx)
+void ArrayPrototype::method_reduceRight(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject instance(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject instance(scope, callData->thisObject.toObject(scope.engine));
if (!instance)
- return Encode::undefined();
+ RETURN_UNDEFINED();
uint len = instance->getLength();
- ScopedFunctionObject callback(scope, ctx->argument(0));
+ ScopedFunctionObject callback(scope, callData->argument(0));
if (!callback)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
if (len == 0) {
- if (ctx->argc() == 1)
- return ctx->engine()->throwTypeError();
- return ctx->argument(1);
+ if (callData->argc == 1)
+ THROW_TYPE_ERROR();
+ scope.result = callData->argument(1);
+ return;
}
uint k = len;
ScopedValue v(scope);
- if (ctx->argc() > 1) {
- scope.result = ctx->argument(1);
+ if (callData->argc > 1) {
+ scope.result = callData->argument(1);
} else {
bool kPresent = false;
while (k > 0 && !kPresent) {
@@ -1023,24 +1004,24 @@ ReturnedValue ArrayPrototype::method_reduceRight(CallContext *ctx)
--k;
}
if (!kPresent)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
}
- ScopedCallData callData(scope, 4);
- callData->thisObject = Primitive::undefinedValue();
- callData->args[3] = instance;
+ ScopedCallData cData(scope, 4);
+ cData->thisObject = Primitive::undefinedValue();
+ cData->args[3] = instance;
while (k > 0) {
bool kPresent;
v = instance->getIndexed(k - 1, &kPresent);
if (kPresent) {
- callData->args[0] = scope.result;
- callData->args[1] = v;
- callData->args[2] = Primitive::fromDouble(k - 1);
- callback->call(scope, callData);
+ cData->args[0] = scope.result;
+ cData->args[1] = v;
+ cData->args[2] = Primitive::fromDouble(k - 1);
+ callback->call(scope, cData);
}
--k;
}
- return scope.result.asReturnedValue();
+ scope.result = scope.result.asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4arrayobject_p.h b/src/qml/jsruntime/qv4arrayobject_p.h
index f00c0c0249..689752433b 100644
--- a/src/qml/jsruntime/qv4arrayobject_p.h
+++ b/src/qml/jsruntime/qv4arrayobject_p.h
@@ -78,30 +78,30 @@ struct ArrayPrototype: ArrayObject
{
void init(ExecutionEngine *engine, Object *ctor);
- static ReturnedValue method_isArray(CallContext *ctx);
- static ReturnedValue method_toString(CallContext *ctx);
- static ReturnedValue method_toLocaleString(CallContext *ctx);
- static ReturnedValue method_concat(CallContext *ctx);
- static ReturnedValue method_find(CallContext *ctx);
- static ReturnedValue method_findIndex(CallContext *ctx);
- static ReturnedValue method_join(CallContext *ctx);
- static ReturnedValue method_pop(CallContext *ctx);
- static ReturnedValue method_push(CallContext *ctx);
- static ReturnedValue method_reverse(CallContext *ctx);
- static ReturnedValue method_shift(CallContext *ctx);
- static ReturnedValue method_slice(CallContext *ctx);
- static ReturnedValue method_sort(CallContext *ctx);
- static ReturnedValue method_splice(CallContext *ctx);
- static ReturnedValue method_unshift(CallContext *ctx);
- static ReturnedValue method_indexOf(CallContext *ctx);
- static ReturnedValue method_lastIndexOf(CallContext *ctx);
- static ReturnedValue method_every(CallContext *ctx);
- static ReturnedValue method_some(CallContext *ctx);
- static ReturnedValue method_forEach(CallContext *ctx);
- static ReturnedValue method_map(CallContext *ctx);
- static ReturnedValue method_filter(CallContext *ctx);
- static ReturnedValue method_reduce(CallContext *ctx);
- static ReturnedValue method_reduceRight(CallContext *ctx);
+ static void method_isArray(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_toString(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_toLocaleString(const BuiltinFunction *builtin, Scope &, CallData *callData);
+ static void method_concat(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_find(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_findIndex(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_join(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_pop(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_push(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_reverse(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_shift(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_slice(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_sort(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_splice(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_unshift(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_indexOf(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_lastIndexOf(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_every(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_some(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_forEach(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_map(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_filter(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_reduce(const BuiltinFunction *, Scope &, CallData *callData);
+ static void method_reduceRight(const BuiltinFunction *, Scope &, CallData *callData);
};
diff --git a/src/qml/jsruntime/qv4booleanobject.cpp b/src/qml/jsruntime/qv4booleanobject.cpp
index 8047993266..601066110f 100644
--- a/src/qml/jsruntime/qv4booleanobject.cpp
+++ b/src/qml/jsruntime/qv4booleanobject.cpp
@@ -73,29 +73,31 @@ void BooleanPrototype::init(ExecutionEngine *engine, Object *ctor)
defineDefaultProperty(engine->id_valueOf(), method_valueOf);
}
-ReturnedValue BooleanPrototype::method_toString(CallContext *ctx)
+void BooleanPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
bool result;
- if (ctx->thisObject().isBoolean()) {
- result = ctx->thisObject().booleanValue();
+ if (callData->thisObject.isBoolean()) {
+ result = callData->thisObject.booleanValue();
} else {
- const BooleanObject *thisObject = ctx->thisObject().as<BooleanObject>();
+ const BooleanObject *thisObject = callData->thisObject.as<BooleanObject>();
if (!thisObject)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
result = thisObject->value();
}
- return Encode(ctx->d()->engine->newString(QLatin1String(result ? "true" : "false")));
+ scope.result = scope.engine->newString(QLatin1String(result ? "true" : "false"));
}
-ReturnedValue BooleanPrototype::method_valueOf(CallContext *ctx)
+void BooleanPrototype::method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->thisObject().isBoolean())
- return ctx->thisObject().asReturnedValue();
+ if (callData->thisObject.isBoolean()) {
+ scope.result = callData->thisObject.asReturnedValue();
+ return;
+ }
- const BooleanObject *thisObject = ctx->thisObject().as<BooleanObject>();
+ const BooleanObject *thisObject = callData->thisObject.as<BooleanObject>();
if (!thisObject)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- return Encode(thisObject->value());
+ scope.result = Encode(thisObject->value());
}
diff --git a/src/qml/jsruntime/qv4booleanobject_p.h b/src/qml/jsruntime/qv4booleanobject_p.h
index 4c2f3c09e7..9c8b1d67f1 100644
--- a/src/qml/jsruntime/qv4booleanobject_p.h
+++ b/src/qml/jsruntime/qv4booleanobject_p.h
@@ -78,8 +78,8 @@ struct BooleanPrototype: BooleanObject
{
void init(ExecutionEngine *engine, Object *ctor);
- static ReturnedValue method_toString(CallContext *ctx);
- static ReturnedValue method_valueOf(CallContext *ctx);
+ static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData);
};
diff --git a/src/qml/jsruntime/qv4context.cpp b/src/qml/jsruntime/qv4context.cpp
index 544d39339b..60b90e4bf0 100644
--- a/src/qml/jsruntime/qv4context.cpp
+++ b/src/qml/jsruntime/qv4context.cpp
@@ -95,6 +95,17 @@ Heap::CallContext *ExecutionContext::newCallContext(Function *function, CallData
return c;
}
+Heap::CallContext *Heap::CallContext::createSimpleContext(ExecutionEngine *v4)
+{
+ Heap::CallContext *ctxt = v4->memoryManager->allocSimpleCallContext(v4);
+ return ctxt;
+}
+
+void Heap::CallContext::freeSimpleCallContext()
+{
+ engine->memoryManager->freeSimpleCallContext();
+}
+
Heap::WithContext *ExecutionContext::newWithContext(Heap::Object *with)
{
return d()->engine->memoryManager->alloc<WithContext>(d(), with);
@@ -325,26 +336,27 @@ void QV4::ExecutionContext::simpleCall(Scope &scope, CallData *callData, Functio
ExecutionContextSaver ctxSaver(scope);
- CallContext::Data ctx = CallContext::Data::createOnStack(scope.engine);
+ CallContext::Data *ctx = scope.engine->memoryManager->allocSimpleCallContext(scope.engine);
- ctx.strictMode = function->isStrict();
- ctx.callData = callData;
- ctx.v4Function = function;
- ctx.compilationUnit = function->compilationUnit;
- ctx.lookups = function->compilationUnit->runtimeLookups;
- ctx.constantTable = function->compilationUnit->constants;
- ctx.outer = this->d();
- ctx.locals = scope.alloc(function->compiledFunction->nLocals);
+ ctx->strictMode = function->isStrict();
+ ctx->callData = callData;
+ ctx->v4Function = function;
+ ctx->compilationUnit = function->compilationUnit;
+ ctx->lookups = function->compilationUnit->runtimeLookups;
+ ctx->constantTable = function->compilationUnit->constants;
+ ctx->outer = this->d();
+ ctx->locals = scope.alloc(function->compiledFunction->nLocals);
for (int i = callData->argc; i < (int)function->nFormals; ++i)
callData->args[i] = Encode::undefined();
- scope.engine->pushContext(&ctx);
- Q_ASSERT(scope.engine->current == &ctx);
+ scope.engine->pushContext(ctx);
+ Q_ASSERT(scope.engine->current == ctx);
scope.result = Q_V4_PROFILE(scope.engine, function);
if (function->hasQmlDependencies)
QQmlPropertyCapture::registerQmlDependencies(function->compiledFunction, scope);
+ scope.engine->memoryManager->freeSimpleCallContext();
}
void ExecutionContext::setProperty(String *name, const Value &value)
diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h
index c985fdb24d..bcfee2e1f8 100644
--- a/src/qml/jsruntime/qv4context_p.h
+++ b/src/qml/jsruntime/qv4context_p.h
@@ -109,14 +109,8 @@ struct ExecutionContext : Base {
{
Base::init();
- callData = nullptr;
this->engine = engine;
- outer = nullptr;
- lookups = nullptr;
- constantTable = nullptr;
- compilationUnit = nullptr;
type = t;
- strictMode = false;
lineNumber = -1;
}
@@ -135,15 +129,12 @@ struct ExecutionContext : Base {
V4_ASSERT_IS_TRIVIAL(ExecutionContext)
struct CallContext : ExecutionContext {
- static CallContext createOnStack(ExecutionEngine *v4);
+ static CallContext *createSimpleContext(ExecutionEngine *v4);
+ void freeSimpleCallContext();
void init(ExecutionEngine *engine, ContextType t = Type_SimpleCallContext)
{
ExecutionContext::init(engine, t);
- function = 0;
- v4Function = 0;
- locals = 0;
- activation = 0;
}
inline unsigned int formalParameterCount() const;
@@ -247,6 +238,7 @@ struct Q_QML_EXPORT CallContext : public ExecutionContext
inline ReturnedValue argument(int i) const;
bool needsOwnArguments() const;
+
};
inline ReturnedValue CallContext::argument(int i) const {
@@ -289,16 +281,6 @@ inline const WithContext *ExecutionContext::asWithContext() const
return d()->type == Heap::ExecutionContext::Type_WithContext ? static_cast<const WithContext *>(this) : 0;
}
-inline Heap::CallContext Heap::CallContext::createOnStack(ExecutionEngine *v4)
-{
- Heap::CallContext ctxt;
- memset(&ctxt, 0, sizeof(Heap::CallContext));
- ctxt.mm_data = 0;
- ctxt.setVtable(QV4::CallContext::staticVTable());
- ctxt.init(v4);
- return ctxt;
-}
-
} // namespace QV4
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4dataview.cpp b/src/qml/jsruntime/qv4dataview.cpp
index db8376272d..a810b38f24 100644
--- a/src/qml/jsruntime/qv4dataview.cpp
+++ b/src/qml/jsruntime/qv4dataview.cpp
@@ -129,90 +129,84 @@ void DataViewPrototype::init(ExecutionEngine *engine, Object *ctor)
defineDefaultProperty(QStringLiteral("setUInt32"), method_set<unsigned int>, 0);
}
-ReturnedValue DataViewPrototype::method_get_buffer(CallContext *ctx)
+void DataViewPrototype::method_get_buffer(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<DataView> v(scope, ctx->thisObject());
+ Scoped<DataView> v(scope, callData->thisObject);
if (!v)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
- return Encode(v->d()->buffer->asReturnedValue());
+ scope.result = v->d()->buffer;
}
-ReturnedValue DataViewPrototype::method_get_byteLength(CallContext *ctx)
+void DataViewPrototype::method_get_byteLength(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<DataView> v(scope, ctx->thisObject());
+ Scoped<DataView> v(scope, callData->thisObject);
if (!v)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
- return Encode(v->d()->byteLength);
+ scope.result = Encode(v->d()->byteLength);
}
-ReturnedValue DataViewPrototype::method_get_byteOffset(CallContext *ctx)
+void DataViewPrototype::method_get_byteOffset(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<DataView> v(scope, ctx->thisObject());
+ Scoped<DataView> v(scope, callData->thisObject);
if (!v)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
- return Encode(v->d()->byteOffset);
+ scope.result = Encode(v->d()->byteOffset);
}
template <typename T>
-ReturnedValue DataViewPrototype::method_getChar(CallContext *ctx)
+void DataViewPrototype::method_getChar(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<DataView> v(scope, ctx->thisObject());
- if (!v || ctx->argc() < 1)
- return scope.engine->throwTypeError();
- double l = ctx->args()[0].toNumber();
+ Scoped<DataView> v(scope, callData->thisObject);
+ if (!v || callData->argc < 1)
+ THROW_TYPE_ERROR();
+ double l = callData->args[0].toNumber();
uint idx = (uint)l;
if (l != idx || idx + sizeof(T) > v->d()->byteLength)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
idx += v->d()->byteOffset;
T t = T(v->d()->buffer->data->data()[idx]);
- return Encode((int)t);
+ scope.result = Encode((int)t);
}
template <typename T>
-ReturnedValue DataViewPrototype::method_get(CallContext *ctx)
+void DataViewPrototype::method_get(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<DataView> v(scope, ctx->thisObject());
- if (!v || ctx->argc() < 1)
- return scope.engine->throwTypeError();
- double l = ctx->args()[0].toNumber();
+ Scoped<DataView> v(scope, callData->thisObject);
+ if (!v || callData->argc < 1)
+ THROW_TYPE_ERROR();
+ double l = callData->args[0].toNumber();
uint idx = (uint)l;
if (l != idx || idx + sizeof(T) > v->d()->byteLength)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
idx += v->d()->byteOffset;
- bool littleEndian = ctx->argc() < 2 ? false : ctx->args()[1].toBoolean();
+ bool littleEndian = callData->argc < 2 ? false : callData->args[1].toBoolean();
T t = littleEndian
? qFromLittleEndian<T>((uchar *)v->d()->buffer->data->data() + idx)
: qFromBigEndian<T>((uchar *)v->d()->buffer->data->data() + idx);
- return Encode(t);
+ scope.result = Encode(t);
}
template <typename T>
-ReturnedValue DataViewPrototype::method_getFloat(CallContext *ctx)
+void DataViewPrototype::method_getFloat(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<DataView> v(scope, ctx->thisObject());
- if (!v || ctx->argc() < 1)
- return scope.engine->throwTypeError();
- double l = ctx->args()[0].toNumber();
+ Scoped<DataView> v(scope, callData->thisObject);
+ if (!v || callData->argc < 1)
+ THROW_TYPE_ERROR();
+ double l = callData->args[0].toNumber();
uint idx = (uint)l;
if (l != idx || idx + sizeof(T) > v->d()->byteLength)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
idx += v->d()->byteOffset;
- bool littleEndian = ctx->argc() < 2 ? false : ctx->args()[1].toBoolean();
+ bool littleEndian = callData->argc < 2 ? false : callData->args[1].toBoolean();
if (sizeof(T) == 4) {
// float
@@ -223,7 +217,7 @@ ReturnedValue DataViewPrototype::method_getFloat(CallContext *ctx)
u.i = littleEndian
? qFromLittleEndian<uint>((uchar *)v->d()->buffer->data->data() + idx)
: qFromBigEndian<uint>((uchar *)v->d()->buffer->data->data() + idx);
- return Encode(u.f);
+ scope.result = Encode(u.f);
} else {
Q_ASSERT(sizeof(T) == 8);
union {
@@ -233,69 +227,66 @@ ReturnedValue DataViewPrototype::method_getFloat(CallContext *ctx)
u.i = littleEndian
? qFromLittleEndian<quint64>((uchar *)v->d()->buffer->data->data() + idx)
: qFromBigEndian<quint64>((uchar *)v->d()->buffer->data->data() + idx);
- return Encode(u.d);
+ scope.result = Encode(u.d);
}
}
template <typename T>
-ReturnedValue DataViewPrototype::method_setChar(CallContext *ctx)
+void DataViewPrototype::method_setChar(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<DataView> v(scope, ctx->thisObject());
- if (!v || ctx->argc() < 1)
- return scope.engine->throwTypeError();
- double l = ctx->args()[0].toNumber();
+ Scoped<DataView> v(scope, callData->thisObject);
+ if (!v || callData->argc < 1)
+ THROW_TYPE_ERROR();
+ double l = callData->args[0].toNumber();
uint idx = (uint)l;
if (l != idx || idx + sizeof(T) > v->d()->byteLength)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
idx += v->d()->byteOffset;
- int val = ctx->argc() >= 2 ? ctx->args()[1].toInt32() : 0;
+ int val = callData->argc >= 2 ? callData->args[1].toInt32() : 0;
v->d()->buffer->data->data()[idx] = (char)val;
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
template <typename T>
-ReturnedValue DataViewPrototype::method_set(CallContext *ctx)
+void DataViewPrototype::method_set(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<DataView> v(scope, ctx->thisObject());
- if (!v || ctx->argc() < 1)
- return scope.engine->throwTypeError();
- double l = ctx->args()[0].toNumber();
+ Scoped<DataView> v(scope, callData->thisObject);
+ if (!v || callData->argc < 1)
+ THROW_TYPE_ERROR();
+ double l = callData->args[0].toNumber();
uint idx = (uint)l;
if (l != idx || idx + sizeof(T) > v->d()->byteLength)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
idx += v->d()->byteOffset;
- int val = ctx->argc() >= 2 ? ctx->args()[1].toInt32() : 0;
+ int val = callData->argc >= 2 ? callData->args[1].toInt32() : 0;
- bool littleEndian = ctx->argc() < 3 ? false : ctx->args()[2].toBoolean();
+ bool littleEndian = callData->argc < 3 ? false : callData->args[2].toBoolean();
if (littleEndian)
qToLittleEndian<T>(val, (uchar *)v->d()->buffer->data->data() + idx);
else
qToBigEndian<T>(val, (uchar *)v->d()->buffer->data->data() + idx);
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
template <typename T>
-ReturnedValue DataViewPrototype::method_setFloat(CallContext *ctx)
+void DataViewPrototype::method_setFloat(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<DataView> v(scope, ctx->thisObject());
- if (!v || ctx->argc() < 1)
- return scope.engine->throwTypeError();
- double l = ctx->args()[0].toNumber();
+ Scoped<DataView> v(scope, callData->thisObject);
+ if (!v || callData->argc < 1)
+ THROW_TYPE_ERROR();
+ double l = callData->args[0].toNumber();
uint idx = (uint)l;
if (l != idx || idx + sizeof(T) > v->d()->byteLength)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
idx += v->d()->byteOffset;
- double val = ctx->argc() >= 2 ? ctx->args()[1].toNumber() : qt_qnan();
- bool littleEndian = ctx->argc() < 3 ? false : ctx->args()[2].toBoolean();
+ double val = callData->argc >= 2 ? callData->args[1].toNumber() : qt_qnan();
+ bool littleEndian = callData->argc < 3 ? false : callData->args[2].toBoolean();
if (sizeof(T) == 4) {
// float
@@ -320,5 +311,5 @@ ReturnedValue DataViewPrototype::method_setFloat(CallContext *ctx)
else
qToBigEndian(u.i, (uchar *)v->d()->buffer->data->data() + idx);
}
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
diff --git a/src/qml/jsruntime/qv4dataview_p.h b/src/qml/jsruntime/qv4dataview_p.h
index 246124394a..11cc0a6bd9 100644
--- a/src/qml/jsruntime/qv4dataview_p.h
+++ b/src/qml/jsruntime/qv4dataview_p.h
@@ -92,21 +92,21 @@ 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);
+ static void method_get_buffer(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_get_byteLength(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_get_byteOffset(const BuiltinFunction *, Scope &scope, CallData *callData);
template <typename T>
- static ReturnedValue method_getChar(CallContext *ctx);
+ static void method_getChar(const BuiltinFunction *, Scope &scope, CallData *callData);
template <typename T>
- static ReturnedValue method_get(CallContext *ctx);
+ static void method_get(const BuiltinFunction *, Scope &scope, CallData *callData);
template <typename T>
- static ReturnedValue method_getFloat(CallContext *ctx);
+ static void method_getFloat(const BuiltinFunction *, Scope &scope, CallData *callData);
template <typename T>
- static ReturnedValue method_setChar(CallContext *ctx);
+ static void method_setChar(const BuiltinFunction *, Scope &scope, CallData *callData);
template <typename T>
- static ReturnedValue method_set(CallContext *ctx);
+ static void method_set(const BuiltinFunction *, Scope &scope, CallData *callData);
template <typename T>
- static ReturnedValue method_setFloat(CallContext *ctx);
+ static void method_setFloat(const BuiltinFunction *, Scope &scope, CallData *callData);
};
diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp
index 8cc6a25fea..b90c335b1c 100644
--- a/src/qml/jsruntime/qv4dateobject.cpp
+++ b/src/qml/jsruntime/qv4dateobject.cpp
@@ -780,435 +780,435 @@ void DatePrototype::init(ExecutionEngine *engine, Object *ctor)
defineDefaultProperty(QStringLiteral("toJSON"), method_toJSON, 1);
}
-double DatePrototype::getThisDate(ExecutionContext *ctx)
+double DatePrototype::getThisDate(Scope &scope, CallData *callData)
{
- if (DateObject *thisObject = ctx->thisObject().as<DateObject>())
+ if (DateObject *thisObject = callData->thisObject.as<DateObject>())
return thisObject->date();
else {
- ctx->engine()->throwTypeError();
+ scope.engine->throwTypeError();
return 0;
}
}
-ReturnedValue DatePrototype::method_parse(CallContext *ctx)
+void DatePrototype::method_parse(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (!ctx->argc())
- return Encode(qt_qnan());
- return Encode(ParseString(ctx->args()[0].toQString()));
+ if (!callData->argc)
+ scope.result = Encode(qt_qnan());
+ else
+ scope.result = Encode(ParseString(callData->args[0].toQString()));
}
-ReturnedValue DatePrototype::method_UTC(CallContext *ctx)
+void DatePrototype::method_UTC(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- const int numArgs = ctx->argc();
+ const int numArgs = callData->argc;
if (numArgs >= 2) {
- double year = ctx->args()[0].toNumber();
- double month = ctx->args()[1].toNumber();
- double day = numArgs >= 3 ? ctx->args()[2].toNumber() : 1;
- double hours = numArgs >= 4 ? ctx->args()[3].toNumber() : 0;
- double mins = numArgs >= 5 ? ctx->args()[4].toNumber() : 0;
- double secs = numArgs >= 6 ? ctx->args()[5].toNumber() : 0;
- double ms = numArgs >= 7 ? ctx->args()[6].toNumber() : 0;
+ double year = callData->args[0].toNumber();
+ double month = callData->args[1].toNumber();
+ double day = numArgs >= 3 ? callData->args[2].toNumber() : 1;
+ double hours = numArgs >= 4 ? callData->args[3].toNumber() : 0;
+ double mins = numArgs >= 5 ? callData->args[4].toNumber() : 0;
+ double secs = numArgs >= 6 ? callData->args[5].toNumber() : 0;
+ double ms = numArgs >= 7 ? callData->args[6].toNumber() : 0;
if (year >= 0 && year <= 99)
year += 1900;
double t = MakeDate(MakeDay(year, month, day),
MakeTime(hours, mins, secs, ms));
- return Encode(TimeClip(t));
+ scope.result = Encode(TimeClip(t));
+ return;
}
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
-ReturnedValue DatePrototype::method_now(CallContext *ctx)
+void DatePrototype::method_now(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Q_UNUSED(ctx);
+ Q_UNUSED(callData);
double t = currentTime();
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_toString(CallContext *ctx)
+void DatePrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- return ctx->d()->engine->newString(ToString(t))->asReturnedValue();
+ double t = getThisDate(scope, callData);
+ scope.result = scope.engine->newString(ToString(t));
}
-ReturnedValue DatePrototype::method_toDateString(CallContext *ctx)
+void DatePrototype::method_toDateString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- return ctx->d()->engine->newString(ToDateString(t))->asReturnedValue();
+ double t = getThisDate(scope, callData);
+ scope.result = scope.engine->newString(ToDateString(t));
}
-ReturnedValue DatePrototype::method_toTimeString(CallContext *ctx)
+void DatePrototype::method_toTimeString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- return ctx->d()->engine->newString(ToTimeString(t))->asReturnedValue();
+ double t = getThisDate(scope, callData);
+ scope.result = scope.engine->newString(ToTimeString(t));
}
-ReturnedValue DatePrototype::method_toLocaleString(CallContext *ctx)
+void DatePrototype::method_toLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- return ctx->d()->engine->newString(ToLocaleString(t))->asReturnedValue();
+ double t = getThisDate(scope, callData);
+ scope.result = scope.engine->newString(ToLocaleString(t));
}
-ReturnedValue DatePrototype::method_toLocaleDateString(CallContext *ctx)
+void DatePrototype::method_toLocaleDateString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- return ctx->d()->engine->newString(ToLocaleDateString(t))->asReturnedValue();
+ double t = getThisDate(scope, callData);
+ scope.result = scope.engine->newString(ToLocaleDateString(t));
}
-ReturnedValue DatePrototype::method_toLocaleTimeString(CallContext *ctx)
+void DatePrototype::method_toLocaleTimeString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- return ctx->d()->engine->newString(ToLocaleTimeString(t))->asReturnedValue();
+ double t = getThisDate(scope, callData);
+ scope.result = scope.engine->newString(ToLocaleTimeString(t));
}
-ReturnedValue DatePrototype::method_valueOf(CallContext *ctx)
+void DatePrototype::method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- return Encode(t);
+ double t = getThisDate(scope, callData);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getTime(CallContext *ctx)
+void DatePrototype::method_getTime(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- return Encode(t);
+ double t = getThisDate(scope, callData);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getYear(CallContext *ctx)
+void DatePrototype::method_getYear(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = YearFromTime(LocalTime(t)) - 1900;
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getFullYear(CallContext *ctx)
+void DatePrototype::method_getFullYear(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = YearFromTime(LocalTime(t));
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getUTCFullYear(CallContext *ctx)
+void DatePrototype::method_getUTCFullYear(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = YearFromTime(t);
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getMonth(CallContext *ctx)
+void DatePrototype::method_getMonth(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = MonthFromTime(LocalTime(t));
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getUTCMonth(CallContext *ctx)
+void DatePrototype::method_getUTCMonth(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = MonthFromTime(t);
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getDate(CallContext *ctx)
+void DatePrototype::method_getDate(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = DateFromTime(LocalTime(t));
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getUTCDate(CallContext *ctx)
+void DatePrototype::method_getUTCDate(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = DateFromTime(t);
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getDay(CallContext *ctx)
+void DatePrototype::method_getDay(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = WeekDay(LocalTime(t));
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getUTCDay(CallContext *ctx)
+void DatePrototype::method_getUTCDay(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = WeekDay(t);
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getHours(CallContext *ctx)
+void DatePrototype::method_getHours(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = HourFromTime(LocalTime(t));
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getUTCHours(CallContext *ctx)
+void DatePrototype::method_getUTCHours(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = HourFromTime(t);
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getMinutes(CallContext *ctx)
+void DatePrototype::method_getMinutes(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = MinFromTime(LocalTime(t));
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getUTCMinutes(CallContext *ctx)
+void DatePrototype::method_getUTCMinutes(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = MinFromTime(t);
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getSeconds(CallContext *ctx)
+void DatePrototype::method_getSeconds(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = SecFromTime(LocalTime(t));
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getUTCSeconds(CallContext *ctx)
+void DatePrototype::method_getUTCSeconds(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = SecFromTime(t);
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getMilliseconds(CallContext *ctx)
+void DatePrototype::method_getMilliseconds(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = msFromTime(LocalTime(t));
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getUTCMilliseconds(CallContext *ctx)
+void DatePrototype::method_getUTCMilliseconds(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = msFromTime(t);
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_getTimezoneOffset(CallContext *ctx)
+void DatePrototype::method_getTimezoneOffset(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double t = getThisDate(ctx);
- if (! std::isnan(t))
+ double t = getThisDate(scope, callData);
+ if (!std::isnan(t))
t = (t - LocalTime(t)) / msPerMinute;
- return Encode(t);
+ scope.result = Encode(t);
}
-ReturnedValue DatePrototype::method_setTime(CallContext *ctx)
+void DatePrototype::method_setTime(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<DateObject> self(scope, ctx->thisObject());
+ Scoped<DateObject> self(scope, callData->thisObject);
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- double t = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
+ double t = callData->argc ? callData->args[0].toNumber() : qt_qnan();
self->setDate(TimeClip(t));
- return Encode(self->date());
+ scope.result = Encode(self->date());
}
-ReturnedValue DatePrototype::method_setMilliseconds(CallContext *ctx)
+void DatePrototype::method_setMilliseconds(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<DateObject> self(scope, ctx->thisObject());
+ Scoped<DateObject> self(scope, callData->thisObject);
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
double t = LocalTime(self->date());
- double ms = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
+ double ms = callData->argc ? callData->args[0].toNumber() : qt_qnan();
self->setDate(TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms)))));
- return Encode(self->date());
+ scope.result = Encode(self->date());
}
-ReturnedValue DatePrototype::method_setUTCMilliseconds(CallContext *ctx)
+void DatePrototype::method_setUTCMilliseconds(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- DateObject *self = ctx->thisObject().as<DateObject>();
+ DateObject *self = callData->thisObject.as<DateObject>();
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
double t = self->date();
- double ms = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
+ double ms = callData->argc ? callData->args[0].toNumber() : qt_qnan();
self->setDate(TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms))));
- return Encode(self->date());
+ scope.result = Encode(self->date());
}
-ReturnedValue DatePrototype::method_setSeconds(CallContext *ctx)
+void DatePrototype::method_setSeconds(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- DateObject *self = ctx->thisObject().as<DateObject>();
+ DateObject *self = callData->thisObject.as<DateObject>();
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
double t = LocalTime(self->date());
- double sec = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
- double ms = (ctx->argc() < 2) ? msFromTime(t) : ctx->args()[1].toNumber();
+ double sec = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double ms = (callData->argc < 2) ? msFromTime(t) : callData->args[1].toNumber();
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms))));
self->setDate(t);
- return Encode(self->date());
+ scope.result = Encode(self->date());
}
-ReturnedValue DatePrototype::method_setUTCSeconds(CallContext *ctx)
+void DatePrototype::method_setUTCSeconds(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- DateObject *self = ctx->thisObject().as<DateObject>();
+ DateObject *self = callData->thisObject.as<DateObject>();
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
double t = self->date();
- double sec = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
- double ms = (ctx->argc() < 2) ? msFromTime(t) : ctx->args()[1].toNumber();
+ double sec = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double ms = (callData->argc < 2) ? msFromTime(t) : callData->args[1].toNumber();
t = TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), sec, ms)));
self->setDate(t);
- return Encode(self->date());
+ scope.result = Encode(self->date());
}
-ReturnedValue DatePrototype::method_setMinutes(CallContext *ctx)
+void DatePrototype::method_setMinutes(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- DateObject *self = ctx->thisObject().as<DateObject>();
+ DateObject *self = callData->thisObject.as<DateObject>();
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
double t = LocalTime(self->date());
- double min = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
- double sec = (ctx->argc() < 2) ? SecFromTime(t) : ctx->args()[1].toNumber();
- double ms = (ctx->argc() < 3) ? msFromTime(t) : ctx->args()[2].toNumber();
+ double min = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double sec = (callData->argc < 2) ? SecFromTime(t) : callData->args[1].toNumber();
+ double ms = (callData->argc < 3) ? msFromTime(t) : callData->args[2].toNumber();
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms))));
self->setDate(t);
- return Encode(self->date());
+ scope.result = Encode(self->date());
}
-ReturnedValue DatePrototype::method_setUTCMinutes(CallContext *ctx)
+void DatePrototype::method_setUTCMinutes(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- DateObject *self = ctx->thisObject().as<DateObject>();
+ DateObject *self = callData->thisObject.as<DateObject>();
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
double t = self->date();
- double min = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
- double sec = (ctx->argc() < 2) ? SecFromTime(t) : ctx->args()[1].toNumber();
- double ms = (ctx->argc() < 3) ? msFromTime(t) : ctx->args()[2].toNumber();
+ double min = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double sec = (callData->argc < 2) ? SecFromTime(t) : callData->args[1].toNumber();
+ double ms = (callData->argc < 3) ? msFromTime(t) : callData->args[2].toNumber();
t = TimeClip(MakeDate(Day(t), MakeTime(HourFromTime(t), min, sec, ms)));
self->setDate(t);
- return Encode(self->date());
+ scope.result = Encode(self->date());
}
-ReturnedValue DatePrototype::method_setHours(CallContext *ctx)
+void DatePrototype::method_setHours(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- DateObject *self = ctx->thisObject().as<DateObject>();
+ DateObject *self = callData->thisObject.as<DateObject>();
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
double t = LocalTime(self->date());
- double hour = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
- double min = (ctx->argc() < 2) ? MinFromTime(t) : ctx->args()[1].toNumber();
- double sec = (ctx->argc() < 3) ? SecFromTime(t) : ctx->args()[2].toNumber();
- double ms = (ctx->argc() < 4) ? msFromTime(t) : ctx->args()[3].toNumber();
+ double hour = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double min = (callData->argc < 2) ? MinFromTime(t) : callData->args[1].toNumber();
+ double sec = (callData->argc < 3) ? SecFromTime(t) : callData->args[2].toNumber();
+ double ms = (callData->argc < 4) ? msFromTime(t) : callData->args[3].toNumber();
t = TimeClip(UTC(MakeDate(Day(t), MakeTime(hour, min, sec, ms))));
self->setDate(t);
- return Encode(self->date());
+ scope.result = Encode(self->date());
}
-ReturnedValue DatePrototype::method_setUTCHours(CallContext *ctx)
+void DatePrototype::method_setUTCHours(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- DateObject *self = ctx->thisObject().as<DateObject>();
+ DateObject *self = callData->thisObject.as<DateObject>();
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
double t = self->date();
- double hour = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
- double min = (ctx->argc() < 2) ? MinFromTime(t) : ctx->args()[1].toNumber();
- double sec = (ctx->argc() < 3) ? SecFromTime(t) : ctx->args()[2].toNumber();
- double ms = (ctx->argc() < 4) ? msFromTime(t) : ctx->args()[3].toNumber();
+ double hour = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double min = (callData->argc < 2) ? MinFromTime(t) : callData->args[1].toNumber();
+ double sec = (callData->argc < 3) ? SecFromTime(t) : callData->args[2].toNumber();
+ double ms = (callData->argc < 4) ? msFromTime(t) : callData->args[3].toNumber();
t = TimeClip(MakeDate(Day(t), MakeTime(hour, min, sec, ms)));
self->setDate(t);
- return Encode(self->date());
+ scope.result = Encode(self->date());
}
-ReturnedValue DatePrototype::method_setDate(CallContext *ctx)
+void DatePrototype::method_setDate(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- DateObject *self = ctx->thisObject().as<DateObject>();
+ DateObject *self = callData->thisObject.as<DateObject>();
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
double t = LocalTime(self->date());
- double date = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
+ double date = callData->argc ? callData->args[0].toNumber() : qt_qnan();
t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), date), TimeWithinDay(t))));
self->setDate(t);
- return Encode(self->date());
+ scope.result = Encode(self->date());
}
-ReturnedValue DatePrototype::method_setUTCDate(CallContext *ctx)
+void DatePrototype::method_setUTCDate(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- DateObject *self = ctx->thisObject().as<DateObject>();
+ DateObject *self = callData->thisObject.as<DateObject>();
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
double t = self->date();
- double date = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
+ double date = callData->argc ? callData->args[0].toNumber() : qt_qnan();
t = TimeClip(MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), date), TimeWithinDay(t)));
self->setDate(t);
- return Encode(self->date());
+ scope.result = Encode(self->date());
}
-ReturnedValue DatePrototype::method_setMonth(CallContext *ctx)
+void DatePrototype::method_setMonth(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- DateObject *self = ctx->thisObject().as<DateObject>();
+ DateObject *self = callData->thisObject.as<DateObject>();
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
double t = LocalTime(self->date());
- double month = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
- double date = (ctx->argc() < 2) ? DateFromTime(t) : ctx->args()[1].toNumber();
+ double month = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double date = (callData->argc < 2) ? DateFromTime(t) : callData->args[1].toNumber();
t = TimeClip(UTC(MakeDate(MakeDay(YearFromTime(t), month, date), TimeWithinDay(t))));
self->setDate(t);
- return Encode(self->date());
+ scope.result = Encode(self->date());
}
-ReturnedValue DatePrototype::method_setUTCMonth(CallContext *ctx)
+void DatePrototype::method_setUTCMonth(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- DateObject *self = ctx->thisObject().as<DateObject>();
+ DateObject *self = callData->thisObject.as<DateObject>();
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
double t = self->date();
- double month = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
- double date = (ctx->argc() < 2) ? DateFromTime(t) : ctx->args()[1].toNumber();
+ double month = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double date = (callData->argc < 2) ? DateFromTime(t) : callData->args[1].toNumber();
t = TimeClip(MakeDate(MakeDay(YearFromTime(t), month, date), TimeWithinDay(t)));
self->setDate(t);
- return Encode(self->date());
+ scope.result = Encode(self->date());
}
-ReturnedValue DatePrototype::method_setYear(CallContext *ctx)
+void DatePrototype::method_setYear(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- DateObject *self = ctx->thisObject().as<DateObject>();
+ DateObject *self = callData->thisObject.as<DateObject>();
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
double t = self->date();
if (std::isnan(t))
t = 0;
else
t = LocalTime(t);
- double year = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
+ double year = callData->argc ? callData->args[0].toNumber() : qt_qnan();
double r;
if (std::isnan(year)) {
r = qt_qnan();
@@ -1220,49 +1220,49 @@ ReturnedValue DatePrototype::method_setYear(CallContext *ctx)
r = TimeClip(r);
}
self->setDate(r);
- return Encode(self->date());
+ scope.result = Encode(self->date());
}
-ReturnedValue DatePrototype::method_setUTCFullYear(CallContext *ctx)
+void DatePrototype::method_setUTCFullYear(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- DateObject *self = ctx->thisObject().as<DateObject>();
+ DateObject *self = callData->thisObject.as<DateObject>();
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
double t = self->date();
- double year = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
- double month = (ctx->argc() < 2) ? MonthFromTime(t) : ctx->args()[1].toNumber();
- double date = (ctx->argc() < 3) ? DateFromTime(t) : ctx->args()[2].toNumber();
+ double year = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double month = (callData->argc < 2) ? MonthFromTime(t) : callData->args[1].toNumber();
+ double date = (callData->argc < 3) ? DateFromTime(t) : callData->args[2].toNumber();
t = TimeClip(MakeDate(MakeDay(year, month, date), TimeWithinDay(t)));
self->setDate(t);
- return Encode(self->date());
+ scope.result = Encode(self->date());
}
-ReturnedValue DatePrototype::method_setFullYear(CallContext *ctx)
+void DatePrototype::method_setFullYear(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- DateObject *self = ctx->thisObject().as<DateObject>();
+ DateObject *self = callData->thisObject.as<DateObject>();
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
double t = LocalTime(self->date());
if (std::isnan(t))
t = 0;
- double year = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
- double month = (ctx->argc() < 2) ? MonthFromTime(t) : ctx->args()[1].toNumber();
- double date = (ctx->argc() < 3) ? DateFromTime(t) : ctx->args()[2].toNumber();
+ double year = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double month = (callData->argc < 2) ? MonthFromTime(t) : callData->args[1].toNumber();
+ double date = (callData->argc < 3) ? DateFromTime(t) : callData->args[2].toNumber();
t = TimeClip(UTC(MakeDate(MakeDay(year, month, date), TimeWithinDay(t))));
self->setDate(t);
- return Encode(self->date());
+ scope.result = Encode(self->date());
}
-ReturnedValue DatePrototype::method_toUTCString(CallContext *ctx)
+void DatePrototype::method_toUTCString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- DateObject *self = ctx->thisObject().as<DateObject>();
+ DateObject *self = callData->thisObject.as<DateObject>();
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
double t = self->date();
- return ctx->d()->engine->newString(ToUTCString(t))->asReturnedValue();
+ scope.result = scope.engine->newString(ToUTCString(t));
}
static void addZeroPrefixedInt(QString &str, int num, int nDigits)
@@ -1278,21 +1278,21 @@ static void addZeroPrefixedInt(QString &str, int num, int nDigits)
}
}
-ReturnedValue DatePrototype::method_toISOString(CallContext *ctx)
+void DatePrototype::method_toISOString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- DateObject *self = ctx->thisObject().as<DateObject>();
+ DateObject *self = callData->thisObject.as<DateObject>();
if (!self)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
double t = self->date();
if (!std::isfinite(t))
- return ctx->engine()->throwRangeError(ctx->thisObject());
+ RETURN_RESULT(scope.engine->throwRangeError(callData->thisObject));
QString result;
int year = (int)YearFromTime(t);
if (year < 0 || year > 9999) {
if (qAbs(year) >= 1000000)
- return ctx->d()->engine->newString(QStringLiteral("Invalid Date"))->asReturnedValue();
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("Invalid Date")));
result += year < 0 ? QLatin1Char('-') : QLatin1Char('+');
year = qAbs(year);
addZeroPrefixedInt(result, year, 6);
@@ -1313,32 +1313,29 @@ ReturnedValue DatePrototype::method_toISOString(CallContext *ctx)
addZeroPrefixedInt(result, msFromTime(t), 3);
result += QLatin1Char('Z');
- return ctx->d()->engine->newString(result)->asReturnedValue();
+ scope.result = scope.engine->newString(result);
}
-ReturnedValue DatePrototype::method_toJSON(CallContext *ctx)
+void DatePrototype::method_toJSON(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject O(scope, ctx->thisObject().toObject(scope.engine));
- if (scope.hasException())
- return Encode::undefined();
+ ScopedObject O(scope, callData->thisObject.toObject(scope.engine));
+ CHECK_EXCEPTION();
ScopedValue tv(scope, RuntimeHelpers::toPrimitive(O, NUMBER_HINT));
if (tv->isNumber() && !std::isfinite(tv->toNumber()))
- return Encode::null();
+ RETURN_RESULT(Encode::null());
- ScopedString s(scope, ctx->d()->engine->newString(QStringLiteral("toISOString")));
+ ScopedString s(scope, scope.engine->newString(QStringLiteral("toISOString")));
ScopedValue v(scope, O->get(s));
FunctionObject *toIso = v->as<FunctionObject>();
if (!toIso)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- ScopedCallData callData(scope);
- callData->thisObject = ctx->thisObject();
- toIso->call(scope, callData);
- return scope.result.asReturnedValue();
+ ScopedCallData cData(scope);
+ cData->thisObject = callData->thisObject;
+ toIso->call(scope, cData);
}
void DatePrototype::timezoneUpdated()
diff --git a/src/qml/jsruntime/qv4dateobject_p.h b/src/qml/jsruntime/qv4dateobject_p.h
index 835f6adbe0..a56d17f9b1 100644
--- a/src/qml/jsruntime/qv4dateobject_p.h
+++ b/src/qml/jsruntime/qv4dateobject_p.h
@@ -116,57 +116,57 @@ struct DatePrototype: DateObject
{
void init(ExecutionEngine *engine, Object *ctor);
- static double getThisDate(ExecutionContext *ctx);
-
- static ReturnedValue method_parse(CallContext *ctx);
- static ReturnedValue method_UTC(CallContext *ctx);
- static ReturnedValue method_now(CallContext *ctx);
-
- static ReturnedValue method_toString(CallContext *ctx);
- static ReturnedValue method_toDateString(CallContext *ctx);
- static ReturnedValue method_toTimeString(CallContext *ctx);
- static ReturnedValue method_toLocaleString(CallContext *ctx);
- static ReturnedValue method_toLocaleDateString(CallContext *ctx);
- static ReturnedValue method_toLocaleTimeString(CallContext *ctx);
- static ReturnedValue method_valueOf(CallContext *ctx);
- static ReturnedValue method_getTime(CallContext *ctx);
- static ReturnedValue method_getYear(CallContext *ctx);
- static ReturnedValue method_getFullYear(CallContext *ctx);
- static ReturnedValue method_getUTCFullYear(CallContext *ctx);
- static ReturnedValue method_getMonth(CallContext *ctx);
- static ReturnedValue method_getUTCMonth(CallContext *ctx);
- static ReturnedValue method_getDate(CallContext *ctx);
- static ReturnedValue method_getUTCDate(CallContext *ctx);
- static ReturnedValue method_getDay(CallContext *ctx);
- static ReturnedValue method_getUTCDay(CallContext *ctx);
- static ReturnedValue method_getHours(CallContext *ctx);
- static ReturnedValue method_getUTCHours(CallContext *ctx);
- static ReturnedValue method_getMinutes(CallContext *ctx);
- static ReturnedValue method_getUTCMinutes(CallContext *ctx);
- static ReturnedValue method_getSeconds(CallContext *ctx);
- static ReturnedValue method_getUTCSeconds(CallContext *ctx);
- static ReturnedValue method_getMilliseconds(CallContext *ctx);
- static ReturnedValue method_getUTCMilliseconds(CallContext *ctx);
- static ReturnedValue method_getTimezoneOffset(CallContext *ctx);
- static ReturnedValue method_setTime(CallContext *ctx);
- static ReturnedValue method_setMilliseconds(CallContext *ctx);
- static ReturnedValue method_setUTCMilliseconds(CallContext *ctx);
- static ReturnedValue method_setSeconds(CallContext *ctx);
- static ReturnedValue method_setUTCSeconds(CallContext *ctx);
- static ReturnedValue method_setMinutes(CallContext *ctx);
- static ReturnedValue method_setUTCMinutes(CallContext *ctx);
- static ReturnedValue method_setHours(CallContext *ctx);
- static ReturnedValue method_setUTCHours(CallContext *ctx);
- static ReturnedValue method_setDate(CallContext *ctx);
- static ReturnedValue method_setUTCDate(CallContext *ctx);
- static ReturnedValue method_setMonth(CallContext *ctx);
- static ReturnedValue method_setUTCMonth(CallContext *ctx);
- static ReturnedValue method_setYear(CallContext *ctx);
- static ReturnedValue method_setFullYear(CallContext *ctx);
- static ReturnedValue method_setUTCFullYear(CallContext *ctx);
- static ReturnedValue method_toUTCString(CallContext *ctx);
- static ReturnedValue method_toISOString(CallContext *ctx);
- static ReturnedValue method_toJSON(CallContext *ctx);
+ static double getThisDate(Scope &scope, CallData *callData);
+
+ static void method_parse(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_UTC(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_now(const BuiltinFunction *, Scope &scope, CallData *callData);
+
+ static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toDateString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toTimeString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toLocaleDateString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toLocaleTimeString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getTime(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getYear(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getFullYear(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getUTCFullYear(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getMonth(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getUTCMonth(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getDate(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getUTCDate(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getDay(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getUTCDay(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getHours(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getUTCHours(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getMinutes(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getUTCMinutes(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getSeconds(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getUTCSeconds(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getMilliseconds(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getUTCMilliseconds(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getTimezoneOffset(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_setTime(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_setMilliseconds(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_setUTCMilliseconds(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_setSeconds(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_setUTCSeconds(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_setMinutes(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_setUTCMinutes(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_setHours(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_setUTCHours(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_setDate(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_setUTCDate(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_setMonth(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_setUTCMonth(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_setYear(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_setFullYear(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_setUTCFullYear(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toUTCString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toISOString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toJSON(const BuiltinFunction *, Scope &scope, CallData *callData);
static void timezoneUpdated();
};
diff --git a/src/qml/jsruntime/qv4errorobject.cpp b/src/qml/jsruntime/qv4errorobject.cpp
index 597ded6ae1..f290bc5136 100644
--- a/src/qml/jsruntime/qv4errorobject.cpp
+++ b/src/qml/jsruntime/qv4errorobject.cpp
@@ -153,12 +153,11 @@ const char *ErrorObject::className(Heap::ErrorObject::ErrorType t)
Q_UNREACHABLE();
}
-ReturnedValue ErrorObject::method_get_stack(CallContext *ctx)
+void ErrorObject::method_get_stack(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<ErrorObject> This(scope, ctx->thisObject());
+ Scoped<ErrorObject> This(scope, callData->thisObject);
if (!This)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
if (!This->d()->stack) {
QString trace;
for (int i = 0; i < This->d()->stackTrace->count(); ++i) {
@@ -169,9 +168,9 @@ ReturnedValue ErrorObject::method_get_stack(CallContext *ctx)
if (frame.line >= 0)
trace += QLatin1Char(':') + QString::number(frame.line);
}
- This->d()->stack = ctx->d()->engine->newString(trace);
+ This->d()->stack = scope.engine->newString(trace);
}
- return This->d()->stack->asReturnedValue();
+ scope.result = This->d()->stack;
}
void ErrorObject::markObjects(Heap::Base *that, ExecutionEngine *e)
@@ -335,22 +334,20 @@ void ErrorPrototype::init(ExecutionEngine *engine, Object *ctor, Object *obj, He
obj->defineDefaultProperty(engine->id_toString(), method_toString, 0);
}
-ReturnedValue ErrorPrototype::method_toString(CallContext *ctx)
+void ErrorPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
-
- Object *o = ctx->thisObject().as<Object>();
+ Object *o = callData->thisObject.as<Object>();
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- ScopedValue name(scope, o->get(ctx->d()->engine->id_name()));
+ ScopedValue name(scope, o->get(scope.engine->id_name()));
QString qname;
if (name->isUndefined())
qname = QStringLiteral("Error");
else
qname = name->toQString();
- ScopedString s(scope, ctx->d()->engine->newString(QStringLiteral("message")));
+ ScopedString s(scope, scope.engine->newString(QStringLiteral("message")));
ScopedValue message(scope, o->get(s));
QString qmessage;
if (!message->isUndefined())
@@ -365,5 +362,5 @@ ReturnedValue ErrorPrototype::method_toString(CallContext *ctx)
str = qname + QLatin1String(": ") + qmessage;
}
- return ctx->d()->engine->newString(str)->asReturnedValue();
+ scope.result = scope.engine->newString(str)->asReturnedValue();
}
diff --git a/src/qml/jsruntime/qv4errorobject_p.h b/src/qml/jsruntime/qv4errorobject_p.h
index 2b3ab25e2d..9ba9f05234 100644
--- a/src/qml/jsruntime/qv4errorobject_p.h
+++ b/src/qml/jsruntime/qv4errorobject_p.h
@@ -172,7 +172,7 @@ struct ErrorObject: Object {
static const char *className(Heap::ErrorObject::ErrorType t);
- static ReturnedValue method_get_stack(CallContext *ctx);
+ static void method_get_stack(const BuiltinFunction *, Scope &scope, CallData *callData);
static void markObjects(Heap::Base *that, ExecutionEngine *e);
};
@@ -282,7 +282,7 @@ struct ErrorPrototype : ErrorObject
void init(ExecutionEngine *engine, Object *ctor) { init(engine, ctor, this, Heap::ErrorObject::Error); }
static void init(ExecutionEngine *engine, Object *ctor, Object *obj, Heap::ErrorObject::ErrorType t);
- static ReturnedValue method_toString(CallContext *ctx);
+ static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
};
struct EvalErrorPrototype : ErrorObject
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp
index 64f7b98618..b2d89220ea 100644
--- a/src/qml/jsruntime/qv4functionobject.cpp
+++ b/src/qml/jsruntime/qv4functionobject.cpp
@@ -270,23 +270,22 @@ void FunctionPrototype::init(ExecutionEngine *engine, Object *ctor)
}
-ReturnedValue FunctionPrototype::method_toString(CallContext *ctx)
+void FunctionPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- FunctionObject *fun = ctx->thisObject().as<FunctionObject>();
+ FunctionObject *fun = callData->thisObject.as<FunctionObject>();
if (!fun)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- return ctx->d()->engine->newString(QStringLiteral("function() { [code] }"))->asReturnedValue();
+ scope.result = scope.engine->newString(QStringLiteral("function() { [code] }"));
}
-ReturnedValue FunctionPrototype::method_apply(CallContext *ctx)
+void FunctionPrototype::method_apply(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- FunctionObject *o = ctx->thisObject().as<FunctionObject>();
+ FunctionObject *o = callData->thisObject.as<FunctionObject>();
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- Scope scope(ctx);
- ScopedValue arg(scope, ctx->argument(1));
+ ScopedValue arg(scope, callData->argument(1));
ScopedObject arr(scope, arg);
@@ -294,75 +293,71 @@ ReturnedValue FunctionPrototype::method_apply(CallContext *ctx)
if (!arr) {
len = 0;
if (!arg->isNullOrUndefined())
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
} else {
len = arr->getLength();
}
- ScopedCallData callData(scope, len);
+ ScopedCallData cData(scope, len);
if (len) {
if (ArgumentsObject::isNonStrictArgumentsObject(arr) && !arr->cast<ArgumentsObject>()->fullyCreated()) {
QV4::ArgumentsObject *a = arr->cast<ArgumentsObject>();
int l = qMin(len, (uint)a->d()->context->callData->argc);
- memcpy(callData->args, a->d()->context->callData->args, l*sizeof(Value));
+ memcpy(cData->args, a->d()->context->callData->args, l*sizeof(Value));
for (quint32 i = l; i < len; ++i)
- callData->args[i] = Primitive::undefinedValue();
+ cData->args[i] = Primitive::undefinedValue();
} else if (arr->arrayType() == Heap::ArrayData::Simple && !arr->protoHasArray()) {
auto sad = static_cast<Heap::SimpleArrayData *>(arr->arrayData());
uint alen = sad ? sad->len : 0;
if (alen > len)
alen = len;
for (uint i = 0; i < alen; ++i)
- callData->args[i] = sad->data(i);
+ cData->args[i] = sad->data(i);
for (quint32 i = alen; i < len; ++i)
- callData->args[i] = Primitive::undefinedValue();
+ cData->args[i] = Primitive::undefinedValue();
} else {
for (quint32 i = 0; i < len; ++i)
- callData->args[i] = arr->getIndexed(i);
+ cData->args[i] = arr->getIndexed(i);
}
}
- callData->thisObject = ctx->argument(0);
- o->call(scope, callData);
- return scope.result.asReturnedValue();
+ cData->thisObject = callData->argument(0);
+ o->call(scope, cData);
}
-ReturnedValue FunctionPrototype::method_call(CallContext *ctx)
+void FunctionPrototype::method_call(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- FunctionObject *o = ctx->thisObject().as<FunctionObject>();
+ FunctionObject *o = callData->thisObject.as<FunctionObject>();
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- Scope scope(ctx);
- ScopedCallData callData(scope, ctx->argc() ? ctx->argc() - 1 : 0);
- if (ctx->argc()) {
- for (int i = 1; i < ctx->argc(); ++i)
- callData->args[i - 1] = ctx->args()[i];
+ ScopedCallData cData(scope, callData->argc ? callData->argc - 1 : 0);
+ if (callData->argc) {
+ for (int i = 1; i < callData->argc; ++i)
+ cData->args[i - 1] = callData->args[i];
}
- callData->thisObject = ctx->argument(0);
+ cData->thisObject = callData->argument(0);
- o->call(scope, callData);
- return scope.result.asReturnedValue();
+ o->call(scope, cData);
}
-ReturnedValue FunctionPrototype::method_bind(CallContext *ctx)
+void FunctionPrototype::method_bind(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- FunctionObject *target = ctx->thisObject().as<FunctionObject>();
+ FunctionObject *target = callData->thisObject.as<FunctionObject>();
if (!target)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- Scope scope(ctx);
- ScopedValue boundThis(scope, ctx->argument(0));
+ ScopedValue boundThis(scope, callData->argument(0));
Scoped<MemberData> boundArgs(scope, (Heap::MemberData *)0);
- if (ctx->argc() > 1) {
- boundArgs = MemberData::allocate(scope.engine, ctx->argc() - 1);
- boundArgs->d()->size = ctx->argc() - 1;
- memcpy(boundArgs->data(), ctx->args() + 1, (ctx->argc() - 1)*sizeof(Value));
+ if (callData->argc > 1) {
+ boundArgs = MemberData::allocate(scope.engine, callData->argc - 1);
+ boundArgs->d()->size = callData->argc - 1;
+ memcpy(boundArgs->data(), callData->args + 1, (callData->argc - 1)*sizeof(Value));
}
ExecutionContext *global = scope.engine->rootContext();
- return BoundFunction::create(global, target, boundThis, boundArgs)->asReturnedValue();
+ scope.result = BoundFunction::create(global, target, boundThis, boundArgs);
}
DEFINE_OBJECT_VTABLE(ScriptFunction);
@@ -459,22 +454,22 @@ Heap::Object *ScriptFunction::protoForConstructor() const
-DEFINE_OBJECT_VTABLE(BuiltinFunction);
+DEFINE_OBJECT_VTABLE(OldBuiltinFunction);
-void Heap::BuiltinFunction::init(QV4::ExecutionContext *scope, QV4::String *name, ReturnedValue (*code)(QV4::CallContext *))
+void Heap::OldBuiltinFunction::init(QV4::ExecutionContext *scope, QV4::String *name, ReturnedValue (*code)(QV4::CallContext *))
{
Heap::FunctionObject::init(scope, name);
this->code = code;
}
-void BuiltinFunction::construct(const Managed *f, Scope &scope, CallData *)
+void OldBuiltinFunction::construct(const Managed *f, Scope &scope, CallData *)
{
- scope.result = static_cast<const BuiltinFunction *>(f)->internalClass()->engine->throwTypeError();
+ scope.result = static_cast<const OldBuiltinFunction *>(f)->internalClass()->engine->throwTypeError();
}
-void BuiltinFunction::call(const Managed *that, Scope &scope, CallData *callData)
+void OldBuiltinFunction::call(const Managed *that, Scope &scope, CallData *callData)
{
- const BuiltinFunction *f = static_cast<const BuiltinFunction *>(that);
+ const OldBuiltinFunction *f = static_cast<const OldBuiltinFunction *>(that);
ExecutionEngine *v4 = scope.engine;
if (v4->hasException) {
scope.result = Encode::undefined();
@@ -484,15 +479,41 @@ void BuiltinFunction::call(const Managed *that, Scope &scope, CallData *callData
ExecutionContextSaver ctxSaver(scope);
- CallContext::Data ctx = CallContext::Data::createOnStack(v4);
- ctx.strictMode = f->scope()->strictMode; // ### needed? scope or parent context?
- ctx.callData = callData;
- v4->pushContext(&ctx);
- Q_ASSERT(v4->current == &ctx);
+ CallContext::Data *ctx = v4->memoryManager->allocSimpleCallContext(v4);
+ ctx->strictMode = f->scope()->strictMode; // ### needed? scope or parent context?
+ ctx->callData = callData;
+ v4->pushContext(ctx);
+ Q_ASSERT(v4->current == ctx);
scope.result = f->d()->code(static_cast<QV4::CallContext *>(v4->currentContext));
+ v4->memoryManager->freeSimpleCallContext();
+}
+
+DEFINE_OBJECT_VTABLE(BuiltinFunction);
+
+void Heap::BuiltinFunction::init(QV4::ExecutionContext *scope, QV4::String *name, void (*code)(const QV4::BuiltinFunction *, Scope &, CallData *))
+{
+ Heap::FunctionObject::init(scope, name);
+ this->code = code;
+}
+
+void BuiltinFunction::construct(const Managed *f, Scope &scope, CallData *)
+{
+ scope.result = static_cast<const BuiltinFunction *>(f)->internalClass()->engine->throwTypeError();
+}
+
+void BuiltinFunction::call(const Managed *that, Scope &scope, CallData *callData)
+{
+ const BuiltinFunction *f = static_cast<const BuiltinFunction *>(that);
+ ExecutionEngine *v4 = scope.engine;
+ if (v4->hasException) {
+ scope.result = Encode::undefined();
+ return;
+ }
+ f->d()->code(f, scope, callData);
}
+
void IndexedBuiltinFunction::call(const Managed *that, Scope &scope, CallData *callData)
{
const IndexedBuiltinFunction *f = static_cast<const IndexedBuiltinFunction *>(that);
@@ -505,13 +526,14 @@ void IndexedBuiltinFunction::call(const Managed *that, Scope &scope, CallData *c
ExecutionContextSaver ctxSaver(scope);
- CallContext::Data ctx = CallContext::Data::createOnStack(v4);
- ctx.strictMode = f->scope()->strictMode; // ### needed? scope or parent context?
- ctx.callData = callData;
- v4->pushContext(&ctx);
- Q_ASSERT(v4->current == &ctx);
+ CallContext::Data *ctx = v4->memoryManager->allocSimpleCallContext(v4);
+ ctx->strictMode = f->scope()->strictMode; // ### needed? scope or parent context?
+ ctx->callData = callData;
+ v4->pushContext(ctx);
+ Q_ASSERT(v4->current == ctx);
scope.result = f->d()->code(static_cast<QV4::CallContext *>(v4->currentContext), f->d()->index);
+ v4->memoryManager->freeSimpleCallContext();
}
DEFINE_OBJECT_VTABLE(IndexedBuiltinFunction);
diff --git a/src/qml/jsruntime/qv4functionobject_p.h b/src/qml/jsruntime/qv4functionobject_p.h
index a02e89e883..45d7485f1b 100644
--- a/src/qml/jsruntime/qv4functionobject_p.h
+++ b/src/qml/jsruntime/qv4functionobject_p.h
@@ -61,6 +61,8 @@ struct QQmlSourceLocation;
namespace QV4 {
+struct BuiltinFunction;
+
namespace Heap {
struct Q_QML_PRIVATE_EXPORT FunctionObject : Object {
@@ -93,11 +95,16 @@ struct FunctionPrototype : FunctionObject {
void init();
};
-struct Q_QML_EXPORT BuiltinFunction : FunctionObject {
+struct Q_QML_EXPORT OldBuiltinFunction : FunctionObject {
void init(QV4::ExecutionContext *scope, QV4::String *name, ReturnedValue (*code)(QV4::CallContext *));
ReturnedValue (*code)(QV4::CallContext *);
};
+struct Q_QML_EXPORT BuiltinFunction : FunctionObject {
+ void init(QV4::ExecutionContext *scope, QV4::String *name, void (*code)(const QV4::BuiltinFunction *, Scope &, CallData *));
+ void (*code)(const QV4::BuiltinFunction *, Scope &, CallData *);
+};
+
struct IndexedBuiltinFunction : FunctionObject {
inline void init(QV4::ExecutionContext *scope, uint index, ReturnedValue (*code)(QV4::CallContext *ctx, uint index));
ReturnedValue (*code)(QV4::CallContext *, uint index);
@@ -177,16 +184,27 @@ struct FunctionPrototype: FunctionObject
void init(ExecutionEngine *engine, Object *ctor);
- static ReturnedValue method_toString(CallContext *ctx);
- static ReturnedValue method_apply(CallContext *ctx);
- static ReturnedValue method_call(CallContext *ctx);
- static ReturnedValue method_bind(CallContext *ctx);
+ static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_apply(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_call(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_bind(const BuiltinFunction *, Scope &scope, CallData *callData);
};
-struct Q_QML_EXPORT BuiltinFunction: FunctionObject {
+struct Q_QML_EXPORT OldBuiltinFunction : FunctionObject {
+ V4_OBJECT2(OldBuiltinFunction, FunctionObject)
+
+ static void construct(const Managed *, Scope &scope, CallData *);
+ static void call(const Managed *that, Scope &scope, CallData *callData);
+};
+
+struct Q_QML_EXPORT BuiltinFunction : FunctionObject {
V4_OBJECT2(BuiltinFunction, FunctionObject)
- static Heap::BuiltinFunction *create(ExecutionContext *scope, String *name, ReturnedValue (*code)(CallContext *))
+ static Heap::OldBuiltinFunction *create(ExecutionContext *scope, String *name, ReturnedValue (*code)(CallContext *))
+ {
+ return scope->engine()->memoryManager->allocObject<OldBuiltinFunction>(scope, name, code);
+ }
+ static Heap::BuiltinFunction *create(ExecutionContext *scope, String *name, void (*code)(const BuiltinFunction *, Scope &, CallData *))
{
return scope->engine()->memoryManager->allocObject<BuiltinFunction>(scope, name, code);
}
diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h
index 1dbc538be2..66861bf697 100644
--- a/src/qml/jsruntime/qv4global_p.h
+++ b/src/qml/jsruntime/qv4global_p.h
@@ -208,6 +208,7 @@ struct StringObject;
struct ArrayObject;
struct DateObject;
struct FunctionObject;
+struct BuiltinFunction;
struct ErrorObject;
struct ArgumentsObject;
struct Managed;
diff --git a/src/qml/jsruntime/qv4globalobject.cpp b/src/qml/jsruntime/qv4globalobject.cpp
index af92ce1ad8..1bc91f832b 100644
--- a/src/qml/jsruntime/qv4globalobject.cpp
+++ b/src/qml/jsruntime/qv4globalobject.cpp
@@ -423,18 +423,15 @@ static inline int toInt(const QChar &qc, int R)
}
// parseInt [15.1.2.2]
-ReturnedValue GlobalFunctions::method_parseInt(CallContext *ctx)
+void GlobalFunctions::method_parseInt(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedValue inputString(scope, ctx->argument(0));
- ScopedValue radix(scope, ctx->argument(1));
+ ScopedValue inputString(scope, callData->argument(0));
+ ScopedValue radix(scope, callData->argument(1));
int R = radix->isUndefined() ? 0 : radix->toInt32();
// [15.1.2.2] step by step:
QString trimmed = inputString->toQString().trimmed(); // 1 + 2
-
- if (ctx->d()->engine->hasException)
- return Encode::undefined();
+ CHECK_EXCEPTION();
const QChar *pos = trimmed.constData();
const QChar *end = pos + trimmed.length();
@@ -449,7 +446,7 @@ ReturnedValue GlobalFunctions::method_parseInt(CallContext *ctx)
bool stripPrefix = true; // 7
if (R) { // 8
if (R < 2 || R > 36)
- return Encode(std::numeric_limits<double>::quiet_NaN()); // 8a
+ RETURN_RESULT(Encode(std::numeric_limits<double>::quiet_NaN())); // 8a
if (R != 16)
stripPrefix = false; // 8b
} else { // 9
@@ -466,13 +463,13 @@ ReturnedValue GlobalFunctions::method_parseInt(CallContext *ctx)
// 11: Z is progressively built below
// 13: this is handled by the toInt function
if (pos == end) // 12
- return Encode(std::numeric_limits<double>::quiet_NaN());
+ RETURN_RESULT(Encode(std::numeric_limits<double>::quiet_NaN()));
bool overflow = false;
qint64 v_overflow = 0;
unsigned overflow_digit_count = 0;
int d = toInt(*pos++, R);
if (d == -1)
- return Encode(std::numeric_limits<double>::quiet_NaN());
+ RETURN_RESULT(Encode(std::numeric_limits<double>::quiet_NaN()));
qint64 v = d;
while (pos != end) {
d = toInt(*pos++, R);
@@ -499,155 +496,148 @@ ReturnedValue GlobalFunctions::method_parseInt(CallContext *ctx)
if (overflow) {
double result = (double) v_overflow * pow(static_cast<double>(R), static_cast<double>(overflow_digit_count));
result += v;
- return Encode(sign * result);
+ RETURN_RESULT(Encode(sign * result));
} else {
- return Encode(sign * (double) v); // 15
+ RETURN_RESULT(Encode(sign * (double) v)); // 15
}
}
// parseFloat [15.1.2.3]
-ReturnedValue GlobalFunctions::method_parseFloat(CallContext *ctx)
+void GlobalFunctions::method_parseFloat(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
-
// [15.1.2.3] step by step:
- ScopedString inputString(scope, ctx->argument(0), ScopedString::Convert);
- if (scope.engine->hasException)
- return Encode::undefined();
+ ScopedString inputString(scope, callData->argument(0), ScopedString::Convert);
+ CHECK_EXCEPTION();
QString trimmed = inputString->toQString().trimmed(); // 2
// 4:
if (trimmed.startsWith(QLatin1String("Infinity"))
|| trimmed.startsWith(QLatin1String("+Infinity")))
- return Encode(Q_INFINITY);
+ RETURN_RESULT(Encode(Q_INFINITY));
if (trimmed.startsWith(QLatin1String("-Infinity")))
- return Encode(-Q_INFINITY);
+ RETURN_RESULT(Encode(-Q_INFINITY));
QByteArray ba = trimmed.toLatin1();
bool ok;
const char *begin = ba.constData();
const char *end = 0;
double d = qstrtod(begin, &end, &ok);
if (end - begin == 0)
- return Encode(std::numeric_limits<double>::quiet_NaN()); // 3
+ RETURN_RESULT(Encode(std::numeric_limits<double>::quiet_NaN())); // 3
else
- return Encode(d);
+ RETURN_RESULT(Encode(d));
}
/// isNaN [15.1.2.4]
-ReturnedValue GlobalFunctions::method_isNaN(CallContext *ctx)
+void GlobalFunctions::method_isNaN(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (!ctx->argc())
+ if (!callData->argc)
// undefined gets converted to NaN
- return Encode(true);
+ RETURN_RESULT(Encode(true));
- if (ctx->args()[0].integerCompatible())
- return Encode(false);
+ if (callData->args[0].integerCompatible())
+ RETURN_RESULT(Encode(false));
- double d = ctx->args()[0].toNumber();
- return Encode((bool)std::isnan(d));
+ double d = callData->args[0].toNumber();
+ RETURN_RESULT(Encode((bool)std::isnan(d)));
}
/// isFinite [15.1.2.5]
-ReturnedValue GlobalFunctions::method_isFinite(CallContext *ctx)
+void GlobalFunctions::method_isFinite(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (!ctx->argc())
+ if (!callData->argc)
// undefined gets converted to NaN
- return Encode(false);
+ RETURN_RESULT(Encode(false));
- if (ctx->args()[0].integerCompatible())
- return Encode(true);
+ if (callData->args[0].integerCompatible())
+ RETURN_RESULT(Encode(true));
- double d = ctx->args()[0].toNumber();
- return Encode((bool)std::isfinite(d));
+ double d = callData->args[0].toNumber();
+ RETURN_RESULT(Encode((bool)std::isfinite(d)));
}
/// decodeURI [15.1.3.1]
-ReturnedValue GlobalFunctions::method_decodeURI(CallContext *context)
+void GlobalFunctions::method_decodeURI(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (context->argc() == 0)
- return Encode::undefined();
+ if (callData->argc == 0)
+ RETURN_UNDEFINED();
- QString uriString = context->args()[0].toQString();
+ QString uriString = callData->args[0].toQString();
bool ok;
QString out = decode(uriString, DecodeNonReserved, &ok);
if (!ok) {
- Scope scope(context);
- ScopedString s(scope, context->d()->engine->newString(QStringLiteral("malformed URI sequence")));
- return context->engine()->throwURIError(s);
+ ScopedString s(scope, scope.engine->newString(QStringLiteral("malformed URI sequence")));
+ RETURN_RESULT(scope.engine->throwURIError(s));
}
- return context->d()->engine->newString(out)->asReturnedValue();
+ RETURN_RESULT(scope.engine->newString(out));
}
/// decodeURIComponent [15.1.3.2]
-ReturnedValue GlobalFunctions::method_decodeURIComponent(CallContext *context)
+void GlobalFunctions::method_decodeURIComponent(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (context->argc() == 0)
- return Encode::undefined();
+ if (callData->argc == 0)
+ RETURN_UNDEFINED();
- QString uriString = context->args()[0].toQString();
+ QString uriString = callData->args[0].toQString();
bool ok;
QString out = decode(uriString, DecodeAll, &ok);
if (!ok) {
- Scope scope(context);
- ScopedString s(scope, context->d()->engine->newString(QStringLiteral("malformed URI sequence")));
- return context->engine()->throwURIError(s);
+ ScopedString s(scope, scope.engine->newString(QStringLiteral("malformed URI sequence")));
+ RETURN_RESULT(scope.engine->throwURIError(s));
}
- return context->d()->engine->newString(out)->asReturnedValue();
+ RETURN_RESULT(scope.engine->newString(out));
}
/// encodeURI [15.1.3.3]
-ReturnedValue GlobalFunctions::method_encodeURI(CallContext *context)
+void GlobalFunctions::method_encodeURI(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (context->argc() == 0)
- return Encode::undefined();
+ if (callData->argc == 0)
+ RETURN_UNDEFINED();
- QString uriString = context->args()[0].toQString();
+ QString uriString = callData->args[0].toQString();
bool ok;
QString out = encode(uriString, uriUnescapedReserved, &ok);
if (!ok) {
- Scope scope(context);
- ScopedString s(scope, context->d()->engine->newString(QStringLiteral("malformed URI sequence")));
- return context->engine()->throwURIError(s);
+ ScopedString s(scope, scope.engine->newString(QStringLiteral("malformed URI sequence")));
+ RETURN_RESULT(scope.engine->throwURIError(s));
}
- return context->d()->engine->newString(out)->asReturnedValue();
+ RETURN_RESULT(scope.engine->newString(out));
}
/// encodeURIComponent [15.1.3.4]
-ReturnedValue GlobalFunctions::method_encodeURIComponent(CallContext *context)
+void GlobalFunctions::method_encodeURIComponent(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (context->argc() == 0)
- return Encode::undefined();
+ if (callData->argc == 0)
+ RETURN_UNDEFINED();
- QString uriString = context->args()[0].toQString();
+ QString uriString = callData->args[0].toQString();
bool ok;
QString out = encode(uriString, uriUnescaped, &ok);
if (!ok) {
- Scope scope(context);
- ScopedString s(scope, context->d()->engine->newString(QStringLiteral("malformed URI sequence")));
- return context->engine()->throwURIError(s);
+ ScopedString s(scope, scope.engine->newString(QStringLiteral("malformed URI sequence")));
+ RETURN_RESULT(scope.engine->throwURIError(s));
}
- return context->d()->engine->newString(out)->asReturnedValue();
+ RETURN_RESULT(scope.engine->newString(out));
}
-ReturnedValue GlobalFunctions::method_escape(CallContext *context)
+void GlobalFunctions::method_escape(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (!context->argc())
- return context->d()->engine->newString(QStringLiteral("undefined"))->asReturnedValue();
+ if (!callData->argc)
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("undefined")));
- QString str = context->args()[0].toQString();
- return context->d()->engine->newString(escape(str))->asReturnedValue();
+ QString str = callData->args[0].toQString();
+ RETURN_RESULT(scope.engine->newString(escape(str)));
}
-ReturnedValue GlobalFunctions::method_unescape(CallContext *context)
+void GlobalFunctions::method_unescape(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (!context->argc())
- return context->d()->engine->newString(QStringLiteral("undefined"))->asReturnedValue();
+ if (!callData->argc)
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("undefined")));
- QString str = context->args()[0].toQString();
- return context->d()->engine->newString(unescape(str))->asReturnedValue();
+ QString str = callData->args[0].toQString();
+ RETURN_RESULT(scope.engine->newString(unescape(str)));
}
diff --git a/src/qml/jsruntime/qv4globalobject_p.h b/src/qml/jsruntime/qv4globalobject_p.h
index e8b3a92d34..273f1ba7ea 100644
--- a/src/qml/jsruntime/qv4globalobject_p.h
+++ b/src/qml/jsruntime/qv4globalobject_p.h
@@ -76,16 +76,16 @@ struct Q_QML_EXPORT EvalFunction : FunctionObject
struct GlobalFunctions
{
- static ReturnedValue method_parseInt(CallContext *context);
- static ReturnedValue method_parseFloat(CallContext *context);
- static ReturnedValue method_isNaN(CallContext *context);
- static ReturnedValue method_isFinite(CallContext *ctx);
- static ReturnedValue method_decodeURI(CallContext *context);
- static ReturnedValue method_decodeURIComponent(CallContext *context);
- static ReturnedValue method_encodeURI(CallContext *context);
- static ReturnedValue method_encodeURIComponent(CallContext *context);
- static ReturnedValue method_escape(CallContext *context);
- static ReturnedValue method_unescape(CallContext *context);
+ static void method_parseInt(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_parseFloat(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_isNaN(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_isFinite(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_decodeURI(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_decodeURIComponent(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_encodeURI(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_encodeURIComponent(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_escape(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_unescape(const BuiltinFunction *, Scope &scope, CallData *callData);
};
}
diff --git a/src/qml/jsruntime/qv4include.cpp b/src/qml/jsruntime/qv4include.cpp
index 1d393cf0aa..f033eb2d2d 100644
--- a/src/qml/jsruntime/qv4include.cpp
+++ b/src/qml/jsruntime/qv4include.cpp
@@ -195,23 +195,22 @@ void QV4Include::finished()
/*
Documented in qv8engine.cpp
*/
-QV4::ReturnedValue QV4Include::method_include(QV4::CallContext *ctx)
+void QV4Include::method_include(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- if (!ctx->argc())
- return QV4::Encode::undefined();
+ if (!callData->argc)
+ RETURN_UNDEFINED();
- QV4::Scope scope(ctx->engine());
QQmlContextData *context = scope.engine->callingQmlContext();
if (!context || !context->isJSContext)
- V4THROW_ERROR("Qt.include(): Can only be called from JavaScript files");
+ RETURN_RESULT(scope.engine->throwError(QString::fromUtf8("Qt.include(): Can only be called from JavaScript files")));
QV4::ScopedValue callbackFunction(scope, QV4::Primitive::undefinedValue());
- if (ctx->argc() >= 2 && ctx->args()[1].as<QV4::FunctionObject>())
- callbackFunction = ctx->args()[1];
+ if (callData->argc >= 2 && callData->args[1].as<QV4::FunctionObject>())
+ callbackFunction = callData->args[1];
#if QT_CONFIG(qml_network)
- QUrl url(scope.engine->resolvedUrl(ctx->args()[0].toQStringNoThrow()));
+ QUrl url(scope.engine->resolvedUrl(callData->args[0].toQStringNoThrow()));
if (scope.engine->qmlEngine() && scope.engine->qmlEngine()->urlInterceptor())
url = scope.engine->qmlEngine()->urlInterceptor()->intercept(url, QQmlAbstractUrlInterceptor::JavaScriptFile);
@@ -261,12 +260,12 @@ QV4::ReturnedValue QV4Include::method_include(QV4::CallContext *ctx)
callback(callbackFunction, result);
}
- return result->asReturnedValue();
+ scope.result = result;
#else
QV4::ScopedValue result(scope);
result = resultValue(scope.engine, NetworkError);
callback(callbackFunction, result);
- return result->asReturnedValue();
+ scope.result = result;
#endif
}
diff --git a/src/qml/jsruntime/qv4include_p.h b/src/qml/jsruntime/qv4include_p.h
index 4c601a5e7b..5908d6bfde 100644
--- a/src/qml/jsruntime/qv4include_p.h
+++ b/src/qml/jsruntime/qv4include_p.h
@@ -77,7 +77,7 @@ public:
Exception = 3
};
- static QV4::ReturnedValue method_include(QV4::CallContext *ctx);
+ static void method_include(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
private Q_SLOTS:
void finished();
diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp
index d17da9af0c..bac71b4537 100644
--- a/src/qml/jsruntime/qv4internalclass.cpp
+++ b/src/qml/jsruntime/qv4internalclass.cpp
@@ -128,48 +128,22 @@ InternalClass::InternalClass(const QV4::InternalClass &other)
static void insertHoleIntoPropertyData(Object *object, int idx)
{
- int inlineSize = object->d()->inlineMemberSize;
int icSize = object->internalClass()->size;
- int from = qMax(idx, inlineSize);
+ int from = idx;
int to = from + 1;
- if (from < icSize) {
+ if (from < icSize)
memmove(object->propertyData(to), object->propertyData(from),
(icSize - from - 1) * sizeof(Value));
- }
- if (from == idx)
- return;
- if (inlineSize < icSize)
- *object->propertyData(inlineSize) = *object->propertyData(inlineSize - 1);
- from = idx;
- to = from + 1;
- if (from < inlineSize - 1) {
- memmove(object->propertyData(to), object->propertyData(from),
- (inlineSize - from - 1) * sizeof(Value));
- }
}
static void removeFromPropertyData(Object *object, int idx, bool accessor = false)
{
- int inlineSize = object->d()->inlineMemberSize;
int delta = (accessor ? 2 : 1);
int oldSize = object->internalClass()->size + delta;
int to = idx;
int from = to + delta;
- if (from < inlineSize) {
- memmove(object->propertyData(to), object->d()->propertyData(from), (inlineSize - from)*sizeof(Value));
- to = inlineSize - delta;
- from = inlineSize;
- }
- if (to < inlineSize && from < oldSize) {
- Q_ASSERT(from >= inlineSize);
- memcpy(object->propertyData(to), object->d()->propertyData(from), (inlineSize - to)*sizeof(Value));
- to = inlineSize;
- from = inlineSize + delta;
- }
- if (from < oldSize) {
- Q_ASSERT(to >= inlineSize && from > to);
+ if (from < oldSize)
memmove(object->propertyData(to), object->d()->propertyData(from), (oldSize - to)*sizeof(Value));
- }
}
void InternalClass::changeMember(Object *object, String *string, PropertyAttributes data, uint *index)
diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp
index d79e6242ba..1d571f53f3 100644
--- a/src/qml/jsruntime/qv4jsonobject.cpp
+++ b/src/qml/jsruntime/qv4jsonobject.cpp
@@ -883,10 +883,9 @@ void Heap::JsonObject::init()
}
-ReturnedValue JsonObject::method_parse(CallContext *ctx)
+void JsonObject::method_parse(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedValue v(scope, ctx->argument(0));
+ ScopedValue v(scope, callData->argument(0));
QString jtext = v->toQString();
DEBUG << "parsing source = " << jtext;
@@ -895,19 +894,17 @@ ReturnedValue JsonObject::method_parse(CallContext *ctx)
ScopedValue result(scope, parser.parse(&error));
if (error.error != QJsonParseError::NoError) {
DEBUG << "parse error" << error.errorString();
- return ctx->engine()->throwSyntaxError(QStringLiteral("JSON.parse: Parse error"));
+ RETURN_RESULT(scope.engine->throwSyntaxError(QStringLiteral("JSON.parse: Parse error")));
}
- return result->asReturnedValue();
+ scope.result = result;
}
-ReturnedValue JsonObject::method_stringify(CallContext *ctx)
+void JsonObject::method_stringify(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
-
Stringify stringify(scope.engine);
- ScopedObject o(scope, ctx->argument(1));
+ ScopedObject o(scope, callData->argument(1));
if (o) {
stringify.replacerFunction = o->as<FunctionObject>();
if (o->isArrayObject()) {
@@ -932,7 +929,7 @@ ReturnedValue JsonObject::method_stringify(CallContext *ctx)
}
}
- ScopedValue s(scope, ctx->argument(2));
+ ScopedValue s(scope, callData->argument(2));
if (NumberObject *n = s->as<NumberObject>())
s = Encode(n->value());
else if (StringObject *so = s->as<StringObject>())
@@ -945,11 +942,11 @@ ReturnedValue JsonObject::method_stringify(CallContext *ctx)
}
- ScopedValue arg0(scope, ctx->argument(0));
+ ScopedValue arg0(scope, callData->argument(0));
QString result = stringify.Str(QString(), arg0);
if (result.isEmpty() || scope.engine->hasException)
- return Encode::undefined();
- return ctx->d()->engine->newString(result)->asReturnedValue();
+ RETURN_UNDEFINED();
+ scope.result = scope.engine->newString(result);
}
diff --git a/src/qml/jsruntime/qv4jsonobject_p.h b/src/qml/jsruntime/qv4jsonobject_p.h
index 43248a214d..a73ce1c74e 100644
--- a/src/qml/jsruntime/qv4jsonobject_p.h
+++ b/src/qml/jsruntime/qv4jsonobject_p.h
@@ -88,8 +88,8 @@ private:
typedef QSet<ObjectItem> V4ObjectSet;
public:
- static ReturnedValue method_parse(CallContext *ctx);
- static ReturnedValue method_stringify(CallContext *ctx);
+ static void method_parse(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_stringify(const BuiltinFunction *, Scope &scope, CallData *callData);
static ReturnedValue fromJsonValue(ExecutionEngine *engine, const QJsonValue &value);
static ReturnedValue fromJsonObject(ExecutionEngine *engine, const QJsonObject &object);
diff --git a/src/qml/jsruntime/qv4mathobject.cpp b/src/qml/jsruntime/qv4mathobject.cpp
index e03b2762cc..2d9d81c64b 100644
--- a/src/qml/jsruntime/qv4mathobject.cpp
+++ b/src/qml/jsruntime/qv4mathobject.cpp
@@ -92,160 +92,160 @@ static Q_ALWAYS_INLINE double copySign(double x, double y)
return ::copysign(x, y);
}
-ReturnedValue MathObject::method_abs(CallContext *context)
+void MathObject::method_abs(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (!context->argc())
- return Encode(qt_qnan());
+ if (!callData->argc)
+ RETURN_RESULT(Encode(qt_qnan()));
- if (context->args()[0].isInteger()) {
- int i = context->args()[0].integerValue();
- return Encode(i < 0 ? - i : i);
+ if (callData->args[0].isInteger()) {
+ int i = callData->args[0].integerValue();
+ RETURN_RESULT(Encode(i < 0 ? - i : i));
}
- double v = context->args()[0].toNumber();
+ double v = callData->args[0].toNumber();
if (v == 0) // 0 | -0
- return Encode(0);
+ RETURN_RESULT(Encode(0));
- return Encode(v < 0 ? -v : v);
+ RETURN_RESULT(Encode(v < 0 ? -v : v));
}
-ReturnedValue MathObject::method_acos(CallContext *context)
+void MathObject::method_acos(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double v = context->argc() ? context->args()[0].toNumber() : 2;
+ double v = callData->argc ? callData->args[0].toNumber() : 2;
if (v > 1)
- return Encode(qt_qnan());
+ RETURN_RESULT(Encode(qt_qnan()));
- return Encode(std::acos(v));
+ RETURN_RESULT(Encode(std::acos(v)));
}
-ReturnedValue MathObject::method_asin(CallContext *context)
+void MathObject::method_asin(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double v = context->argc() ? context->args()[0].toNumber() : 2;
+ double v = callData->argc ? callData->args[0].toNumber() : 2;
if (v > 1)
- return Encode(qt_qnan());
+ RETURN_RESULT(Encode(qt_qnan()));
else
- return Encode(std::asin(v));
+ RETURN_RESULT(Encode(std::asin(v)));
}
-ReturnedValue MathObject::method_atan(CallContext *context)
+void MathObject::method_atan(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double v = context->argc() ? context->args()[0].toNumber() : qt_qnan();
+ double v = callData->argc ? callData->args[0].toNumber() : qt_qnan();
if (v == 0.0)
- return Encode(v);
+ RETURN_RESULT(Encode(v));
else
- return Encode(std::atan(v));
+ RETURN_RESULT(Encode(std::atan(v)));
}
-ReturnedValue MathObject::method_atan2(CallContext *context)
+void MathObject::method_atan2(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double v1 = context->argc() ? context->args()[0].toNumber() : qt_qnan();
- double v2 = context->argc() > 1 ? context->args()[1].toNumber() : qt_qnan();
+ double v1 = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ double v2 = callData->argc > 1 ? callData->args[1].toNumber() : qt_qnan();
if ((v1 < 0) && qt_is_finite(v1) && qt_is_inf(v2) && (copySign(1.0, v2) == 1.0))
- return Encode(copySign(0, -1.0));
+ RETURN_RESULT(Encode(copySign(0, -1.0)));
if ((v1 == 0.0) && (v2 == 0.0)) {
if ((copySign(1.0, v1) == 1.0) && (copySign(1.0, v2) == -1.0)) {
- return Encode(M_PI);
+ RETURN_RESULT(Encode(M_PI));
} else if ((copySign(1.0, v1) == -1.0) && (copySign(1.0, v2) == -1.0)) {
- return Encode(-M_PI);
+ RETURN_RESULT(Encode(-M_PI));
}
}
- return Encode(std::atan2(v1, v2));
+ RETURN_RESULT(Encode(std::atan2(v1, v2)));
}
-ReturnedValue MathObject::method_ceil(CallContext *context)
+void MathObject::method_ceil(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double v = context->argc() ? context->args()[0].toNumber() : qt_qnan();
+ double v = callData->argc ? callData->args[0].toNumber() : qt_qnan();
if (v < 0.0 && v > -1.0)
- return Encode(copySign(0, -1.0));
+ RETURN_RESULT(Encode(copySign(0, -1.0)));
else
- return Encode(std::ceil(v));
+ RETURN_RESULT(Encode(std::ceil(v)));
}
-ReturnedValue MathObject::method_cos(CallContext *context)
+void MathObject::method_cos(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double v = context->argc() ? context->args()[0].toNumber() : qt_qnan();
- return Encode(std::cos(v));
+ double v = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ RETURN_RESULT(Encode(std::cos(v)));
}
-ReturnedValue MathObject::method_exp(CallContext *context)
+void MathObject::method_exp(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double v = context->argc() ? context->args()[0].toNumber() : qt_qnan();
+ double v = callData->argc ? callData->args[0].toNumber() : qt_qnan();
if (qt_is_inf(v)) {
if (copySign(1.0, v) == -1.0)
- return Encode(0);
+ RETURN_RESULT(Encode(0));
else
- return Encode(qt_inf());
+ RETURN_RESULT(Encode(qt_inf()));
} else {
- return Encode(std::exp(v));
+ RETURN_RESULT(Encode(std::exp(v)));
}
}
-ReturnedValue MathObject::method_floor(CallContext *context)
+void MathObject::method_floor(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double v = context->argc() ? context->args()[0].toNumber() : qt_qnan();
- return Encode(std::floor(v));
+ double v = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ RETURN_RESULT(Encode(std::floor(v)));
}
-ReturnedValue MathObject::method_log(CallContext *context)
+void MathObject::method_log(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double v = context->argc() ? context->args()[0].toNumber() : qt_qnan();
+ double v = callData->argc ? callData->args[0].toNumber() : qt_qnan();
if (v < 0)
- return Encode(qt_qnan());
+ RETURN_RESULT(Encode(qt_qnan()));
else
- return Encode(std::log(v));
+ RETURN_RESULT(Encode(std::log(v)));
}
-ReturnedValue MathObject::method_max(CallContext *context)
+void MathObject::method_max(const BuiltinFunction *, Scope &scope, CallData *callData)
{
double mx = -qt_inf();
- for (int i = 0; i < context->argc(); ++i) {
- double x = context->args()[i].toNumber();
+ for (int i = 0; i < callData->argc; ++i) {
+ double x = callData->args[i].toNumber();
if (x > mx || std::isnan(x))
mx = x;
}
- return Encode(mx);
+ RETURN_RESULT(Encode(mx));
}
-ReturnedValue MathObject::method_min(CallContext *context)
+void MathObject::method_min(const BuiltinFunction *, Scope &scope, CallData *callData)
{
double mx = qt_inf();
- for (int i = 0; i < context->argc(); ++i) {
- double x = context->args()[i].toNumber();
+ for (int i = 0; i < callData->argc; ++i) {
+ double x = callData->args[i].toNumber();
if ((x == 0 && mx == x && copySign(1.0, x) == -1.0)
|| (x < mx) || std::isnan(x)) {
mx = x;
}
}
- return Encode(mx);
+ RETURN_RESULT(Encode(mx));
}
-ReturnedValue MathObject::method_pow(CallContext *context)
+void MathObject::method_pow(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double x = context->argc() > 0 ? context->args()[0].toNumber() : qt_qnan();
- double y = context->argc() > 1 ? context->args()[1].toNumber() : qt_qnan();
+ double x = callData->argc > 0 ? callData->args[0].toNumber() : qt_qnan();
+ double y = callData->argc > 1 ? callData->args[1].toNumber() : qt_qnan();
if (std::isnan(y))
- return Encode(qt_qnan());
+ RETURN_RESULT(Encode(qt_qnan()));
if (y == 0) {
- return Encode(1);
+ RETURN_RESULT(Encode(1));
} else if (((x == 1) || (x == -1)) && std::isinf(y)) {
- return Encode(qt_qnan());
+ RETURN_RESULT(Encode(qt_qnan()));
} else if (((x == 0) && copySign(1.0, x) == 1.0) && (y < 0)) {
- return Encode(qInf());
+ RETURN_RESULT(Encode(qInf()));
} else if ((x == 0) && copySign(1.0, x) == -1.0) {
if (y < 0) {
if (std::fmod(-y, 2.0) == 1.0)
- return Encode(-qt_inf());
+ RETURN_RESULT(Encode(-qt_inf()));
else
- return Encode(qt_inf());
+ RETURN_RESULT(Encode(qt_inf()));
} else if (y > 0) {
if (std::fmod(y, 2.0) == 1.0)
- return Encode(copySign(0, -1.0));
+ RETURN_RESULT(Encode(copySign(0, -1.0)));
else
- return Encode(0);
+ RETURN_RESULT(Encode(0));
}
}
@@ -253,78 +253,78 @@ ReturnedValue MathObject::method_pow(CallContext *context)
else if (qt_is_inf(x) && copySign(1.0, x) == -1.0) {
if (y > 0) {
if (std::fmod(y, 2.0) == 1.0)
- return Encode(-qt_inf());
+ RETURN_RESULT(Encode(-qt_inf()));
else
- return Encode(qt_inf());
+ RETURN_RESULT(Encode(qt_inf()));
} else if (y < 0) {
if (std::fmod(-y, 2.0) == 1.0)
- return Encode(copySign(0, -1.0));
+ RETURN_RESULT(Encode(copySign(0, -1.0)));
else
- return Encode(0);
+ RETURN_RESULT(Encode(0));
}
}
#endif
else {
- return Encode(std::pow(x, y));
+ RETURN_RESULT(Encode(std::pow(x, y)));
}
// ###
- return Encode(qt_qnan());
+ RETURN_RESULT(Encode(qt_qnan()));
}
Q_GLOBAL_STATIC(QThreadStorage<bool *>, seedCreatedStorage);
-ReturnedValue MathObject::method_random(CallContext *context)
+void MathObject::method_random(const BuiltinFunction *, Scope &scope, CallData *)
{
if (!seedCreatedStorage()->hasLocalData()) {
int msecs = QTime(0,0,0).msecsTo(QTime::currentTime());
Q_ASSERT(msecs >= 0);
- qsrand(uint(uint(msecs) ^ reinterpret_cast<quintptr>(context)));
+ qsrand(uint(uint(msecs) ^ reinterpret_cast<quintptr>(scope.engine)));
seedCreatedStorage()->setLocalData(new bool(true));
}
// rand()/qrand() return a value where the upperbound is RAND_MAX inclusive. So, instead of
// dividing by RAND_MAX (which would return 0..RAND_MAX inclusive), we divide by RAND_MAX + 1.
qint64 upperLimit = qint64(RAND_MAX) + 1;
- return Encode(qrand() / double(upperLimit));
+ RETURN_RESULT(Encode(qrand() / double(upperLimit)));
}
-ReturnedValue MathObject::method_round(CallContext *context)
+void MathObject::method_round(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double v = context->argc() ? context->args()[0].toNumber() : qt_qnan();
+ double v = callData->argc ? callData->args[0].toNumber() : qt_qnan();
v = copySign(std::floor(v + 0.5), v);
- return Encode(v);
+ RETURN_RESULT(Encode(v));
}
-ReturnedValue MathObject::method_sign(CallContext *context)
+void MathObject::method_sign(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double v = context->argc() ? context->args()[0].toNumber() : qt_qnan();
+ double v = callData->argc ? callData->args[0].toNumber() : qt_qnan();
if (std::isnan(v))
- return Encode(qt_qnan());
+ RETURN_RESULT(Encode(qt_qnan()));
if (qIsNull(v))
- return v;
+ RETURN_RESULT(Encode(v));
- return Encode(std::signbit(v) ? -1 : 1);
+ RETURN_RESULT(Encode(std::signbit(v) ? -1 : 1));
}
-ReturnedValue MathObject::method_sin(CallContext *context)
+void MathObject::method_sin(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double v = context->argc() ? context->args()[0].toNumber() : qt_qnan();
- return Encode(std::sin(v));
+ double v = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ RETURN_RESULT(Encode(std::sin(v)));
}
-ReturnedValue MathObject::method_sqrt(CallContext *context)
+void MathObject::method_sqrt(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double v = context->argc() ? context->args()[0].toNumber() : qt_qnan();
- return Encode(std::sqrt(v));
+ double v = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+ RETURN_RESULT(Encode(std::sqrt(v)));
}
-ReturnedValue MathObject::method_tan(CallContext *context)
+void MathObject::method_tan(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- double v = context->argc() ? context->args()[0].toNumber() : qt_qnan();
+ double v = callData->argc ? callData->args[0].toNumber() : qt_qnan();
if (v == 0.0)
- return Encode(v);
+ RETURN_RESULT(Encode(v));
else
- return Encode(std::tan(v));
+ RETURN_RESULT(Encode(std::tan(v)));
}
diff --git a/src/qml/jsruntime/qv4mathobject_p.h b/src/qml/jsruntime/qv4mathobject_p.h
index f6b1a4395f..e617712905 100644
--- a/src/qml/jsruntime/qv4mathobject_p.h
+++ b/src/qml/jsruntime/qv4mathobject_p.h
@@ -69,25 +69,25 @@ struct MathObject: Object
V4_OBJECT2(MathObject, Object)
Q_MANAGED_TYPE(MathObject)
- static ReturnedValue method_abs(CallContext *context);
- static ReturnedValue method_acos(CallContext *context);
- static ReturnedValue method_asin(CallContext *context);
- static ReturnedValue method_atan(CallContext *context);
- static ReturnedValue method_atan2(CallContext *context);
- static ReturnedValue method_ceil(CallContext *context);
- static ReturnedValue method_cos(CallContext *context);
- static ReturnedValue method_exp(CallContext *context);
- static ReturnedValue method_floor(CallContext *context);
- static ReturnedValue method_log(CallContext *context);
- static ReturnedValue method_max(CallContext *context);
- static ReturnedValue method_min(CallContext *context);
- static ReturnedValue method_pow(CallContext *context);
- static ReturnedValue method_random(CallContext *context);
- static ReturnedValue method_round(CallContext *context);
- static ReturnedValue method_sign(CallContext *context);
- static ReturnedValue method_sin(CallContext *context);
- static ReturnedValue method_sqrt(CallContext *context);
- static ReturnedValue method_tan(CallContext *context);
+ static void method_abs(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_acos(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_asin(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_atan(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_atan2(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_ceil(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_cos(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_exp(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_floor(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_log(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_max(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_min(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_pow(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_random(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_round(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_sign(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_sin(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_sqrt(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_tan(const BuiltinFunction *, Scope &scope, CallData *callData);
};
}
diff --git a/src/qml/jsruntime/qv4memberdata.cpp b/src/qml/jsruntime/qv4memberdata.cpp
index d5f75415cc..f2a24f8179 100644
--- a/src/qml/jsruntime/qv4memberdata.cpp
+++ b/src/qml/jsruntime/qv4memberdata.cpp
@@ -56,12 +56,12 @@ Heap::MemberData *MemberData::allocate(ExecutionEngine *e, uint n, Heap::MemberD
{
Q_ASSERT(!old || old->size < n);
- uint alloc = sizeof(Heap::MemberData) + (n)*sizeof(Value);
+ size_t alloc = MemoryManager::align(sizeof(Heap::MemberData) + (n - 1)*sizeof(Value));
Heap::MemberData *m = e->memoryManager->allocManaged<MemberData>(alloc);
if (old)
- memcpy(m, old, sizeof(Heap::MemberData) + old->size * sizeof(Value));
+ memcpy(m, old, sizeof(Heap::MemberData) + (old->size - 1)* sizeof(Value));
else
m->init();
- m->size = n;
+ m->size = static_cast<uint>((alloc - sizeof(Heap::MemberData) + sizeof(Value))/sizeof(Value));
return m;
}
diff --git a/src/qml/jsruntime/qv4numberobject.cpp b/src/qml/jsruntime/qv4numberobject.cpp
index 3a6b9da763..09644c161d 100644
--- a/src/qml/jsruntime/qv4numberobject.cpp
+++ b/src/qml/jsruntime/qv4numberobject.cpp
@@ -120,61 +120,71 @@ QT_WARNING_POP
defineDefaultProperty(QStringLiteral("toPrecision"), method_toPrecision);
}
-inline ReturnedValue thisNumberValue(ExecutionContext *ctx)
+inline ReturnedValue thisNumberValue(Scope &scope, CallData *callData)
{
- if (ctx->thisObject().isNumber())
- return ctx->thisObject().asReturnedValue();
- NumberObject *n = ctx->thisObject().as<NumberObject>();
- if (!n)
- return ctx->engine()->throwTypeError();
+ if (callData->thisObject.isNumber())
+ return callData->thisObject.asReturnedValue();
+ NumberObject *n = callData->thisObject.as<NumberObject>();
+ if (!n) {
+ scope.engine->throwTypeError();
+ return Encode::undefined();
+ }
return Encode(n->value());
}
-inline double thisNumber(ExecutionContext *ctx)
+inline double thisNumber(Scope &scope, CallData *callData)
{
- if (ctx->thisObject().isNumber())
- return ctx->thisObject().asDouble();
- NumberObject *n = ctx->thisObject().as<NumberObject>();
- if (!n)
- return ctx->engine()->throwTypeError();
+ if (callData->thisObject.isNumber())
+ return callData->thisObject.asDouble();
+ NumberObject *n = callData->thisObject.as<NumberObject>();
+ if (!n) {
+ scope.engine->throwTypeError();
+ return 0;
+ }
return n->value();
}
-ReturnedValue NumberPrototype::method_isFinite(CallContext *ctx)
+void NumberPrototype::method_isFinite(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (!ctx->argc())
- return Encode(false);
+ if (!callData->argc) {
+ scope.result = Encode(false);
+ return;
+ }
- double v = ctx->args()[0].toNumber();
- return Encode(!std::isnan(v) && !qt_is_inf(v));
+ double v = callData->args[0].toNumber();
+ scope.result = Encode(!std::isnan(v) && !qt_is_inf(v));
}
-ReturnedValue NumberPrototype::method_isNaN(CallContext *ctx)
+void NumberPrototype::method_isNaN(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (!ctx->argc())
- return Encode(false);
+ if (!callData->argc) {
+ scope.result = Encode(false);
+ return;
+ }
- double v = ctx->args()[0].toNumber();
- return Encode(std::isnan(v));
+ double v = callData->args[0].toNumber();
+ scope.result = Encode(std::isnan(v));
}
-ReturnedValue NumberPrototype::method_toString(CallContext *ctx)
+void NumberPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- double num = thisNumber(ctx);
- if (scope.engine->hasException)
- return Encode::undefined();
+ double num = thisNumber(scope, callData);
+ CHECK_EXCEPTION();
- if (ctx->argc() && !ctx->args()[0].isUndefined()) {
- int radix = ctx->args()[0].toInt32();
- if (radix < 2 || radix > 36)
- return ctx->engine()->throwError(QStringLiteral("Number.prototype.toString: %0 is not a valid radix")
+ if (callData->argc && !callData->args[0].isUndefined()) {
+ int radix = callData->args[0].toInt32();
+ if (radix < 2 || radix > 36) {
+ scope.result = scope.engine->throwError(QStringLiteral("Number.prototype.toString: %0 is not a valid radix")
.arg(radix));
+ return;
+ }
if (std::isnan(num)) {
- return scope.engine->newString(QStringLiteral("NaN"))->asReturnedValue();
+ scope.result = scope.engine->newString(QStringLiteral("NaN"));
+ return;
} else if (qt_is_inf(num)) {
- return scope.engine->newString(QLatin1String(num < 0 ? "-Infinity" : "Infinity"))->asReturnedValue();
+ scope.result = scope.engine->newString(QLatin1String(num < 0 ? "-Infinity" : "Infinity"));
+ return;
}
if (radix != 10) {
@@ -204,45 +214,43 @@ ReturnedValue NumberPrototype::method_toString(CallContext *ctx)
}
if (negative)
str.prepend(QLatin1Char('-'));
- return scope.engine->newString(str)->asReturnedValue();
+ scope.result = scope.engine->newString(str);
+ return;
}
}
- return Primitive::fromDouble(num).toString(scope.engine)->asReturnedValue();
+ scope.result = Primitive::fromDouble(num).toString(scope.engine);
}
-ReturnedValue NumberPrototype::method_toLocaleString(CallContext *ctx)
+void NumberPrototype::method_toLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedValue v(scope, thisNumberValue(ctx));
- ScopedString str(scope, v->toString(scope.engine));
- if (scope.engine->hasException)
- return Encode::undefined();
- return str.asReturnedValue();
+ ScopedValue v(scope, thisNumberValue(scope, callData));
+ scope.result = v->toString(scope.engine);
+ CHECK_EXCEPTION();
}
-ReturnedValue NumberPrototype::method_valueOf(CallContext *ctx)
+void NumberPrototype::method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- return thisNumberValue(ctx);
+ scope.result = thisNumberValue(scope, callData);
}
-ReturnedValue NumberPrototype::method_toFixed(CallContext *ctx)
+void NumberPrototype::method_toFixed(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- double v = thisNumber(ctx);
- if (scope.engine->hasException)
- return Encode::undefined();
+ double v = thisNumber(scope, callData);
+ CHECK_EXCEPTION();
double fdigits = 0;
- if (ctx->argc() > 0)
- fdigits = ctx->args()[0].toInteger();
+ if (callData->argc > 0)
+ fdigits = callData->args[0].toInteger();
if (std::isnan(fdigits))
fdigits = 0;
- if (fdigits < 0 || fdigits > 20)
- return ctx->engine()->throwRangeError(ctx->thisObject());
+ if (fdigits < 0 || fdigits > 20) {
+ scope.result = scope.engine->throwRangeError(callData->thisObject);
+ return;
+ }
QString str;
if (std::isnan(v))
@@ -251,48 +259,50 @@ ReturnedValue NumberPrototype::method_toFixed(CallContext *ctx)
str = QString::fromLatin1(v < 0 ? "-Infinity" : "Infinity");
else if (v < 1.e21)
str = NumberLocale::instance()->toString(v, 'f', int(fdigits));
- else
- return RuntimeHelpers::stringFromNumber(ctx->engine(), v)->asReturnedValue();
- return scope.engine->newString(str)->asReturnedValue();
+ else {
+ scope.result = RuntimeHelpers::stringFromNumber(scope.engine, v);
+ return;
+ }
+ scope.result = scope.engine->newString(str);
}
-ReturnedValue NumberPrototype::method_toExponential(CallContext *ctx)
+void NumberPrototype::method_toExponential(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- double d = thisNumber(ctx);
- if (scope.engine->hasException)
- return Encode::undefined();
+ double d = thisNumber(scope, callData);
+ CHECK_EXCEPTION();
int fdigits = NumberLocale::instance()->defaultDoublePrecision;
- if (ctx->argc() && !ctx->args()[0].isUndefined()) {
- fdigits = ctx->args()[0].toInt32();
+ if (callData->argc && !callData->args[0].isUndefined()) {
+ fdigits = callData->args[0].toInt32();
if (fdigits < 0 || fdigits > 20) {
ScopedString error(scope, scope.engine->newString(QStringLiteral("Number.prototype.toExponential: fractionDigits out of range")));
- return ctx->engine()->throwRangeError(error);
+ scope.result = scope.engine->throwRangeError(error);
+ return;
}
}
QString result = NumberLocale::instance()->toString(d, 'e', fdigits);
- return scope.engine->newString(result)->asReturnedValue();
+ scope.result = scope.engine->newString(result);
}
-ReturnedValue NumberPrototype::method_toPrecision(CallContext *ctx)
+void NumberPrototype::method_toPrecision(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedValue v(scope, thisNumberValue(ctx));
- if (scope.engine->hasException)
- return Encode::undefined();
+ ScopedValue v(scope, thisNumberValue(scope, callData));
+ CHECK_EXCEPTION();
- if (!ctx->argc() || ctx->args()[0].isUndefined())
- return Encode(v->toString(scope.engine));
+ if (!callData->argc || callData->args[0].isUndefined()) {
+ scope.result = v->toString(scope.engine);
+ return;
+ }
- int precision = ctx->args()[0].toInt32();
+ int precision = callData->args[0].toInt32();
if (precision < 1 || precision > 21) {
ScopedString error(scope, scope.engine->newString(QStringLiteral("Number.prototype.toPrecision: precision out of range")));
- return ctx->engine()->throwRangeError(error);
+ scope.result = scope.engine->throwRangeError(error);
+ return;
}
QString result = NumberLocale::instance()->toString(v->asDouble(), 'g', precision);
- return scope.engine->newString(result)->asReturnedValue();
+ scope.result = scope.engine->newString(result);
}
diff --git a/src/qml/jsruntime/qv4numberobject_p.h b/src/qml/jsruntime/qv4numberobject_p.h
index 6022b3a029..364b866a16 100644
--- a/src/qml/jsruntime/qv4numberobject_p.h
+++ b/src/qml/jsruntime/qv4numberobject_p.h
@@ -87,14 +87,14 @@ struct NumberPrototype: NumberObject
{
void init(ExecutionEngine *engine, Object *ctor);
- static ReturnedValue method_isFinite(CallContext *ctx);
- static ReturnedValue method_isNaN(CallContext *ctx);
- static ReturnedValue method_toString(CallContext *ctx);
- static ReturnedValue method_toLocaleString(CallContext *ctx);
- static ReturnedValue method_valueOf(CallContext *ctx);
- static ReturnedValue method_toFixed(CallContext *ctx);
- static ReturnedValue method_toExponential(CallContext *ctx);
- static ReturnedValue method_toPrecision(CallContext *ctx);
+ static void method_isFinite(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_isNaN(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toFixed(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toExponential(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toPrecision(const BuiltinFunction *, Scope &scope, CallData *callData);
};
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index 8acca16dd0..5d6c479477 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -61,9 +61,8 @@ DEFINE_OBJECT_VTABLE(Object);
void Object::setInternalClass(InternalClass *ic)
{
d()->internalClass = ic;
- if ((ic->size > d()->inlineMemberSize && !d()->memberData) ||
- (d()->memberData && d()->memberData->size < ic->size - d()->inlineMemberSize))
- d()->memberData = MemberData::allocate(ic->engine, ic->size - d()->inlineMemberSize, d()->memberData);
+ if (!d()->memberData || (d()->memberData->size < ic->size))
+ d()->memberData = MemberData::allocate(ic->engine, ic->size, d()->memberData);
}
void Object::getProperty(uint index, Property *p, PropertyAttributes *attrs) const
@@ -167,6 +166,17 @@ void Object::defineDefaultProperty(const QString &name, ReturnedValue (*code)(Ca
defineDefaultProperty(s, function);
}
+void Object::defineDefaultProperty(const QString &name, void (*code)(const BuiltinFunction *, Scope &, CallData *), int argumentCount)
+{
+ ExecutionEngine *e = engine();
+ Scope scope(e);
+ ScopedString s(scope, e->newIdentifier(name));
+ ExecutionContext *global = e->rootContext();
+ ScopedFunctionObject function(scope, BuiltinFunction::create(global, s, code));
+ function->defineReadonlyProperty(e->id_length(), Primitive::fromInt32(argumentCount));
+ defineDefaultProperty(s, function);
+}
+
void Object::defineDefaultProperty(String *name, ReturnedValue (*code)(CallContext *), int argumentCount)
{
ExecutionEngine *e = engine();
@@ -177,6 +187,16 @@ void Object::defineDefaultProperty(String *name, ReturnedValue (*code)(CallConte
defineDefaultProperty(name, function);
}
+void Object::defineDefaultProperty(String *name, void (*code)(const BuiltinFunction *, Scope &, CallData *), int argumentCount)
+{
+ ExecutionEngine *e = engine();
+ Scope scope(e);
+ ExecutionContext *global = e->rootContext();
+ ScopedFunctionObject function(scope, BuiltinFunction::create(global, name, code));
+ function->defineReadonlyProperty(e->id_length(), Primitive::fromInt32(argumentCount));
+ defineDefaultProperty(name, function);
+}
+
void Object::defineAccessorProperty(const QString &name, ReturnedValue (*getter)(CallContext *), ReturnedValue (*setter)(CallContext *))
{
ExecutionEngine *e = engine();
@@ -196,6 +216,27 @@ void Object::defineAccessorProperty(String *name, ReturnedValue (*getter)(CallCo
insertMember(name, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
}
+void Object::defineAccessorProperty(const QString &name, void (*getter)(const BuiltinFunction *, Scope &, CallData *),
+ void (*setter)(const BuiltinFunction *, Scope &, CallData *))
+{
+ ExecutionEngine *e = engine();
+ Scope scope(e);
+ ScopedString s(scope, e->newIdentifier(name));
+ defineAccessorProperty(s, getter, setter);
+}
+
+void Object::defineAccessorProperty(String *name, void (*getter)(const BuiltinFunction *, Scope &, CallData *),
+ void (*setter)(const BuiltinFunction *, Scope &, CallData *))
+{
+ ExecutionEngine *v4 = engine();
+ QV4::Scope scope(v4);
+ ScopedProperty p(scope);
+ ExecutionContext *global = v4->rootContext();
+ p->setGetter(ScopedFunctionObject(scope, (getter ? BuiltinFunction::create(global, name, getter) : 0)));
+ p->setSetter(ScopedFunctionObject(scope, (setter ? BuiltinFunction::create(global, name, setter) : 0)));
+ insertMember(name, p, QV4::Attr_Accessor|QV4::Attr_NotConfigurable|QV4::Attr_NotEnumerable);
+}
+
void Object::defineReadonlyProperty(const QString &name, const Value &value)
{
QV4::ExecutionEngine *e = engine();
@@ -213,12 +254,6 @@ void Object::markObjects(Heap::Base *that, ExecutionEngine *e)
{
Heap::Object *o = static_cast<Heap::Object *>(that);
- if (o->inlineMemberSize) {
- Value *v = o->propertyData(0);
- for (uint i = 0; i < o->inlineMemberSize; ++i)
- v[i].mark(e);
- }
-
if (o->memberData)
o->memberData->mark(e);
if (o->arrayData)
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index 6c679deb10..4a78690f47 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -63,17 +63,17 @@ QT_BEGIN_NAMESPACE
namespace QV4 {
+struct BuiltinFunction;
+
namespace Heap {
struct Object : Base {
void init() { Base::init(); }
void destroy() { Base::destroy(); }
- const Value *propertyData(uint index) const { if (index < inlineMemberSize) return reinterpret_cast<const Value *>(this) + inlineMemberOffset + index; return memberData->data + index - inlineMemberSize; }
- Value *propertyData(uint index) { if (index < inlineMemberSize) return reinterpret_cast<Value *>(this) + inlineMemberOffset + index; return memberData->data + index - inlineMemberSize; }
+ const Value *propertyData(uint index) const { return memberData->data + index; }
+ Value *propertyData(uint index) { return memberData->data + index; }
- uint inlineMemberOffset;
- uint inlineMemberSize;
InternalClass *internalClass;
Pointer<Object> prototype;
Pointer<MemberData> memberData;
@@ -238,9 +238,15 @@ struct Q_QML_EXPORT Object: Managed {
}
void defineDefaultProperty(const QString &name, const Value &value);
void defineDefaultProperty(const QString &name, ReturnedValue (*code)(CallContext *), int argumentCount = 0);
+ void defineDefaultProperty(const QString &name, void (*code)(const BuiltinFunction *, Scope &, CallData *), int argumentCount = 0);
void defineDefaultProperty(String *name, ReturnedValue (*code)(CallContext *), int argumentCount = 0);
+ void defineDefaultProperty(String *name, void (*code)(const BuiltinFunction *, Scope &, CallData *), int argumentCount = 0);
void defineAccessorProperty(const QString &name, ReturnedValue (*getter)(CallContext *), ReturnedValue (*setter)(CallContext *));
void defineAccessorProperty(String *name, ReturnedValue (*getter)(CallContext *), ReturnedValue (*setter)(CallContext *));
+ void defineAccessorProperty(const QString &name, void (*getter)(const BuiltinFunction *, Scope &, CallData *),
+ void (*setter)(const BuiltinFunction *, Scope &, CallData *));
+ void defineAccessorProperty(String *name, void (*getter)(const BuiltinFunction *, Scope &, CallData *),
+ void (*setter)(const BuiltinFunction *, Scope &, CallData *));
/* Fixed: Writable: false, Enumerable: false, Configurable: false */
void defineReadonlyProperty(const QString &name, const Value &value);
void defineReadonlyProperty(String *name, const Value &value);
diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp
index 8191083544..97dbe24339 100644
--- a/src/qml/jsruntime/qv4objectproto.cpp
+++ b/src/qml/jsruntime/qv4objectproto.cpp
@@ -121,100 +121,100 @@ void ObjectPrototype::init(ExecutionEngine *v4, Object *ctor)
insertMember(v4->id___proto__(), p, Attr_Accessor|Attr_NotEnumerable);
}
-ReturnedValue ObjectPrototype::method_getPrototypeOf(CallContext *ctx)
+void ObjectPrototype::method_getPrototypeOf(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject o(scope, ctx->argument(0));
+ ScopedObject o(scope, callData->argument(0));
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
ScopedObject p(scope, o->prototype());
- return !!p ? p->asReturnedValue() : Encode::null();
+ scope.result = !!p ? p->asReturnedValue() : Encode::null();
}
-ReturnedValue ObjectPrototype::method_getOwnPropertyDescriptor(CallContext *ctx)
+void ObjectPrototype::method_getOwnPropertyDescriptor(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject O(scope, ctx->argument(0));
- if (!O)
- return ctx->engine()->throwTypeError();
+ ScopedObject O(scope, callData->argument(0));
+ if (!O) {
+ scope.result = scope.engine->throwTypeError();
+ return;
+ }
if (ArgumentsObject::isNonStrictArgumentsObject(O))
static_cast<ArgumentsObject *>(O.getPointer())->fullyCreate();
- ScopedValue v(scope, ctx->argument(1));
+ ScopedValue v(scope, callData->argument(1));
ScopedString name(scope, v->toString(scope.engine));
- if (scope.hasException())
- return Encode::undefined();
+ CHECK_EXCEPTION();
+
PropertyAttributes attrs;
ScopedProperty desc(scope);
O->getOwnProperty(name, &attrs, desc);
- return fromPropertyDescriptor(scope.engine, desc, attrs);
+ scope.result = fromPropertyDescriptor(scope.engine, desc, attrs);
}
-ReturnedValue ObjectPrototype::method_getOwnPropertyNames(CallContext *context)
+void ObjectPrototype::method_getOwnPropertyNames(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(context);
- ScopedObject O(scope, context->argument(0));
- if (!O)
- return context->engine()->throwTypeError();
+ ScopedObject O(scope, callData->argument(0));
+ if (!O) {
+ scope.result = scope.engine->throwTypeError();
+ return;
+ }
- ScopedArrayObject array(scope, getOwnPropertyNames(context->d()->engine, context->args()[0]));
- return array.asReturnedValue();
+ scope.result = getOwnPropertyNames(scope.engine, callData->args[0]);
}
-ReturnedValue ObjectPrototype::method_create(CallContext *ctx)
+void ObjectPrototype::method_create(const BuiltinFunction *builtin, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedValue O(scope, ctx->argument(0));
- if (!O->isObject() && !O->isNull())
- return ctx->engine()->throwTypeError();
+ ScopedValue O(scope, callData->argument(0));
+ if (!O->isObject() && !O->isNull()) {
+ scope.result = scope.engine->throwTypeError();
+ return;
+ }
- ScopedObject newObject(scope, ctx->d()->engine->newObject());
+ ScopedObject newObject(scope, scope.engine->newObject());
newObject->setPrototype(O->as<Object>());
- if (ctx->argc() > 1 && !ctx->args()[1].isUndefined()) {
- ctx->d()->callData->args[0] = newObject.asReturnedValue();
- return method_defineProperties(ctx);
+ if (callData->argc > 1 && !callData->args[1].isUndefined()) {
+ callData->args[0] = newObject;
+ method_defineProperties(builtin, scope, callData);
+ return;
}
- return newObject.asReturnedValue();
+ scope.result = newObject;
}
-ReturnedValue ObjectPrototype::method_defineProperty(CallContext *ctx)
+void ObjectPrototype::method_defineProperty(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject O(scope, ctx->argument(0));
- if (!O)
- return ctx->engine()->throwTypeError();
+ ScopedObject O(scope, callData->argument(0));
+ if (!O) {
+ scope.result = scope.engine->throwTypeError();
+ return;
+ }
- ScopedString name(scope, ctx->argument(1), ScopedString::Convert);
- if (scope.engine->hasException)
- return Encode::undefined();
+ ScopedString name(scope, callData->argument(1), ScopedString::Convert);
+ CHECK_EXCEPTION();
- ScopedValue attributes(scope, ctx->argument(2));
+ ScopedValue attributes(scope, callData->argument(2));
ScopedProperty pd(scope);
PropertyAttributes attrs;
toPropertyDescriptor(scope.engine, attributes, pd, &attrs);
- if (scope.engine->hasException)
- return Encode::undefined();
+ CHECK_EXCEPTION();
if (!O->__defineOwnProperty__(scope.engine, name, pd, attrs))
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- return O.asReturnedValue();
+ scope.result = O;
}
-ReturnedValue ObjectPrototype::method_defineProperties(CallContext *ctx)
+void ObjectPrototype::method_defineProperties(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject O(scope, ctx->argument(0));
+ ScopedObject O(scope, callData->argument(0));
if (!O)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
+
+ ScopedObject o(scope, callData->argument(1), ScopedObject::Convert);
+ CHECK_EXCEPTION();
- ScopedObject o(scope, ctx->argument(1), ScopedObject::Convert);
- if (scope.engine->hasException)
- return Encode::undefined();
ScopedValue val(scope);
ObjectIterator it(scope, o, ObjectIterator::EnumerableOnly);
@@ -230,26 +230,24 @@ ReturnedValue ObjectPrototype::method_defineProperties(CallContext *ctx)
PropertyAttributes nattrs;
val = o->getValue(pd->value, attrs);
toPropertyDescriptor(scope.engine, val, n, &nattrs);
- if (scope.engine->hasException)
- return Encode::undefined();
+ CHECK_EXCEPTION();
bool ok;
if (name)
ok = O->__defineOwnProperty__(scope.engine, name, n, nattrs);
else
ok = O->__defineOwnProperty__(scope.engine, index, n, nattrs);
if (!ok)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
}
- return O.asReturnedValue();
+ scope.result = O;
}
-ReturnedValue ObjectPrototype::method_seal(CallContext *ctx)
+void ObjectPrototype::method_seal(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject o(scope, ctx->argument(0));
+ ScopedObject o(scope, callData->argument(0));
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
o->setInternalClass(o->internalClass()->sealed());
@@ -261,15 +259,14 @@ ReturnedValue ObjectPrototype::method_seal(CallContext *ctx)
}
}
- return o.asReturnedValue();
+ scope.result = o;
}
-ReturnedValue ObjectPrototype::method_freeze(CallContext *ctx)
+void ObjectPrototype::method_freeze(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject o(scope, ctx->argument(0));
+ ScopedObject o(scope, callData->argument(0));
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
if (ArgumentsObject::isNonStrictArgumentsObject(o))
static_cast<ArgumentsObject *>(o.getPointer())->fullyCreate();
@@ -285,96 +282,111 @@ ReturnedValue ObjectPrototype::method_freeze(CallContext *ctx)
o->arrayData()->attrs[i].setWritable(false);
}
}
- return o.asReturnedValue();
+ scope.result = o;
}
-ReturnedValue ObjectPrototype::method_preventExtensions(CallContext *ctx)
+void ObjectPrototype::method_preventExtensions(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject o(scope, ctx->argument(0));
+ ScopedObject o(scope, callData->argument(0));
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
o->setInternalClass(o->internalClass()->nonExtensible());
- return o.asReturnedValue();
+ scope.result = o;
}
-ReturnedValue ObjectPrototype::method_isSealed(CallContext *ctx)
+void ObjectPrototype::method_isSealed(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject o(scope, ctx->argument(0));
+ ScopedObject o(scope, callData->argument(0));
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- if (o->isExtensible())
- return Encode(false);
+ if (o->isExtensible()) {
+ scope.result = Encode(false);
+ return;
+ }
- if (o->internalClass() != o->internalClass()->sealed())
- return Encode(false);
+ if (o->internalClass() != o->internalClass()->sealed()) {
+ scope.result = Encode(false);
+ return;
+ }
- if (!o->arrayData() || !o->arrayData()->length())
- return Encode(true);
+ if (!o->arrayData() || !o->arrayData()->length()) {
+ scope.result = Encode(true);
+ return;
+ }
Q_ASSERT(o->arrayData() && o->arrayData()->length());
- if (!o->arrayData()->attrs)
- return Encode(false);
+ if (!o->arrayData()->attrs) {
+ scope.result = Encode(false);
+ return;
+ }
for (uint i = 0; i < o->arrayData()->alloc; ++i) {
if (!o->arrayData()->isEmpty(i))
- if (o->arrayData()->attributes(i).isConfigurable())
- return Encode(false);
+ if (o->arrayData()->attributes(i).isConfigurable()) {
+ scope.result = Encode(false);
+ return;
+ }
}
- return Encode(true);
+ scope.result = Encode(true);
}
-ReturnedValue ObjectPrototype::method_isFrozen(CallContext *ctx)
+void ObjectPrototype::method_isFrozen(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject o(scope, ctx->argument(0));
+ ScopedObject o(scope, callData->argument(0));
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- if (o->isExtensible())
- return Encode(false);
+ if (o->isExtensible()) {
+ scope.result = Encode(false);
+ return;
+ }
- if (o->internalClass() != o->internalClass()->frozen())
- return Encode(false);
+ if (o->internalClass() != o->internalClass()->frozen()) {
+ scope.result = Encode(false);
+ return;
+ }
- if (!o->arrayData() || !o->arrayData()->length())
- return Encode(true);
+ if (!o->arrayData() || !o->arrayData()->length()) {
+ scope.result = Encode(true);
+ return;
+ }
Q_ASSERT(o->arrayData() && o->arrayData()->length());
- if (!o->arrayData()->attrs)
- return Encode(false);
+ if (!o->arrayData()->attrs) {
+ scope.result = Encode(false);
+ return;
+ }
for (uint i = 0; i < o->arrayData()->alloc; ++i) {
if (!o->arrayData()->isEmpty(i))
- if (o->arrayData()->attributes(i).isConfigurable() || o->arrayData()->attributes(i).isWritable())
- return Encode(false);
+ if (o->arrayData()->attributes(i).isConfigurable() || o->arrayData()->attributes(i).isWritable()) {
+ scope.result = Encode(false);
+ return;
+ }
}
- return Encode(true);
+ scope.result = Encode(true);
}
-ReturnedValue ObjectPrototype::method_isExtensible(CallContext *ctx)
+void ObjectPrototype::method_isExtensible(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject o(scope, ctx->argument(0));
+ ScopedObject o(scope, callData->argument(0));
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- return Encode((bool)o->isExtensible());
+ scope.result = Encode((bool)o->isExtensible());
}
-ReturnedValue ObjectPrototype::method_keys(CallContext *ctx)
+void ObjectPrototype::method_keys(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject o(scope, ctx->argument(0));
+ ScopedObject o(scope, callData->argument(0));
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- ScopedArrayObject a(scope, ctx->d()->engine->newArrayObject());
+ ScopedArrayObject a(scope, scope.engine->newArrayObject());
ObjectIterator it(scope, o, ObjectIterator::EnumerableOnly);
ScopedValue name(scope);
@@ -385,175 +397,159 @@ ReturnedValue ObjectPrototype::method_keys(CallContext *ctx)
a->push_back(name);
}
- return a.asReturnedValue();
+ scope.result = a;
}
-ReturnedValue ObjectPrototype::method_toString(CallContext *ctx)
+void ObjectPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- if (ctx->thisObject().isUndefined()) {
- return ctx->d()->engine->newString(QStringLiteral("[object Undefined]"))->asReturnedValue();
- } else if (ctx->thisObject().isNull()) {
- return ctx->d()->engine->newString(QStringLiteral("[object Null]"))->asReturnedValue();
+ if (callData->thisObject.isUndefined()) {
+ scope.result = scope.engine->newString(QStringLiteral("[object Undefined]"));
+ } else if (callData->thisObject.isNull()) {
+ scope.result = scope.engine->newString(QStringLiteral("[object Null]"));
} else {
- ScopedObject obj(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject obj(scope, callData->thisObject.toObject(scope.engine));
QString className = obj->className();
- return ctx->d()->engine->newString(QStringLiteral("[object %1]").arg(className))->asReturnedValue();
+ scope.result = scope.engine->newString(QStringLiteral("[object %1]").arg(className));
}
}
-ReturnedValue ObjectPrototype::method_toLocaleString(CallContext *ctx)
+void ObjectPrototype::method_toLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject o(scope, ctx->thisObject().toObject(scope.engine));
+ ScopedObject o(scope, callData->thisObject.toObject(scope.engine));
if (!o)
- return Encode::undefined();
- ScopedFunctionObject f(scope, o->get(ctx->d()->engine->id_toString()));
+ RETURN_UNDEFINED();
+
+ ScopedFunctionObject f(scope, o->get(scope.engine->id_toString()));
if (!f)
- return ctx->engine()->throwTypeError();
- ScopedCallData callData(scope);
- callData->thisObject = o;
+ THROW_TYPE_ERROR();
+ ScopedCallData cData(scope);
+ cData->thisObject = o;
f->call(scope, callData);
- return scope.result.asReturnedValue();
}
-ReturnedValue ObjectPrototype::method_valueOf(CallContext *ctx)
+void ObjectPrototype::method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedValue v(scope, ctx->thisObject().toObject(scope.engine));
- if (ctx->d()->engine->hasException)
- return Encode::undefined();
- return v->asReturnedValue();
+ scope.result = callData->thisObject.toObject(scope.engine);
}
-ReturnedValue ObjectPrototype::method_hasOwnProperty(CallContext *ctx)
+void ObjectPrototype::method_hasOwnProperty(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedString P(scope, ctx->argument(0), ScopedString::Convert);
- if (scope.engine->hasException)
- return Encode::undefined();
- ScopedObject O(scope, ctx->thisObject(), ScopedObject::Convert);
- if (scope.engine->hasException)
- return Encode::undefined();
+ ScopedString P(scope, callData->argument(0), ScopedString::Convert);
+ CHECK_EXCEPTION();
+ ScopedObject O(scope, callData->thisObject, ScopedObject::Convert);
+ CHECK_EXCEPTION();
bool r = O->hasOwnProperty(P);
if (!r)
r = !O->query(P).isEmpty();
- return Encode(r);
+ scope.result = Encode(r);
}
-ReturnedValue ObjectPrototype::method_isPrototypeOf(CallContext *ctx)
+void ObjectPrototype::method_isPrototypeOf(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject V(scope, ctx->argument(0));
- if (!V)
- return Encode(false);
+ ScopedObject V(scope, callData->argument(0));
+ if (!V) {
+ scope.result = Encode(false);
+ return;
+ }
- ScopedObject O(scope, ctx->thisObject(), ScopedObject::Convert);
- if (scope.engine->hasException)
- return Encode::undefined();
+ ScopedObject O(scope, callData->thisObject, ScopedObject::Convert);
+ CHECK_EXCEPTION();
ScopedObject proto(scope, V->prototype());
while (proto) {
- if (O->d() == proto->d())
- return Encode(true);
+ if (O->d() == proto->d()) {
+ scope.result = Encode(true);
+ return;
+ }
proto = proto->prototype();
}
- return Encode(false);
+ scope.result = Encode(false);
}
-ReturnedValue ObjectPrototype::method_propertyIsEnumerable(CallContext *ctx)
+void ObjectPrototype::method_propertyIsEnumerable(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedString p(scope, ctx->argument(0), ScopedString::Convert);
- if (scope.engine->hasException)
- return Encode::undefined();
+ ScopedString p(scope, callData->argument(0), ScopedString::Convert);
+ CHECK_EXCEPTION();
- ScopedObject o(scope, ctx->thisObject(), ScopedObject::Convert);
- if (scope.engine->hasException)
- return Encode::undefined();
+ ScopedObject o(scope, callData->thisObject, ScopedObject::Convert);
+ CHECK_EXCEPTION();
PropertyAttributes attrs;
o->getOwnProperty(p, &attrs);
- return Encode(attrs.isEnumerable());
+ scope.result = Encode(attrs.isEnumerable());
}
-ReturnedValue ObjectPrototype::method_defineGetter(CallContext *ctx)
+void ObjectPrototype::method_defineGetter(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() < 2)
- return ctx->engine()->throwTypeError();
+ if (callData->argc < 2)
+ THROW_TYPE_ERROR();
- Scope scope(ctx);
- ScopedFunctionObject f(scope, ctx->argument(1));
+ ScopedFunctionObject f(scope, callData->argument(1));
if (!f)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- ScopedString prop(scope, ctx->argument(0), ScopedString::Convert);
- if (scope.engine->hasException)
- return Encode::undefined();
+ ScopedString prop(scope, callData->argument(0), ScopedString::Convert);
+ CHECK_EXCEPTION();
- ScopedObject o(scope, ctx->thisObject());
+ ScopedObject o(scope, callData->thisObject);
if (!o) {
- if (!ctx->thisObject().isUndefined())
- return Encode::undefined();
- o = ctx->d()->engine->globalObject;
+ if (!callData->thisObject.isUndefined())
+ RETURN_UNDEFINED();
+ o = scope.engine->globalObject;
}
ScopedProperty pd(scope);
pd->value = f;
pd->set = Primitive::emptyValue();
o->__defineOwnProperty__(scope.engine, prop, pd, Attr_Accessor);
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
-ReturnedValue ObjectPrototype::method_defineSetter(CallContext *ctx)
+void ObjectPrototype::method_defineSetter(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() < 2)
- return ctx->engine()->throwTypeError();
+ if (callData->argc < 2)
+ THROW_TYPE_ERROR();
- Scope scope(ctx);
- ScopedFunctionObject f(scope, ctx->argument(1));
+ ScopedFunctionObject f(scope, callData->argument(1));
if (!f)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- ScopedString prop(scope, ctx->argument(0), ScopedString::Convert);
- if (scope.engine->hasException)
- return Encode::undefined();
+ ScopedString prop(scope, callData->argument(0), ScopedString::Convert);
+ CHECK_EXCEPTION();
- ScopedObject o(scope, ctx->thisObject());
+ ScopedObject o(scope, callData->thisObject);
if (!o) {
- if (!ctx->thisObject().isUndefined())
- return Encode::undefined();
- o = ctx->d()->engine->globalObject;
+ if (!callData->thisObject.isUndefined())
+ RETURN_UNDEFINED();
+ o = scope.engine->globalObject;
}
ScopedProperty pd(scope);
pd->value = Primitive::emptyValue();
pd->set = f;
o->__defineOwnProperty__(scope.engine, prop, pd, Attr_Accessor);
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
-ReturnedValue ObjectPrototype::method_get_proto(CallContext *ctx)
+void ObjectPrototype::method_get_proto(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject o(scope, ctx->thisObject().as<Object>());
+ ScopedObject o(scope, callData->thisObject.as<Object>());
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- return o->prototype()->asReturnedValue();
+ scope.result = o->prototype();
}
-ReturnedValue ObjectPrototype::method_set_proto(CallContext *ctx)
+void ObjectPrototype::method_set_proto(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedObject o(scope, ctx->thisObject());
- if (!o || !ctx->argc())
- return ctx->engine()->throwTypeError();
+ ScopedObject o(scope, callData->thisObject);
+ if (!o || !callData->argc)
+ THROW_TYPE_ERROR();
- if (ctx->args()[0].isNull()) {
+ if (callData->args[0].isNull()) {
o->setPrototype(0);
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
- ScopedObject p(scope, ctx->args()[0]);
+ ScopedObject p(scope, callData->args[0]);
bool ok = false;
if (!!p) {
if (o->prototype() == p->d()) {
@@ -562,9 +558,11 @@ ReturnedValue ObjectPrototype::method_set_proto(CallContext *ctx)
ok = o->setPrototype(p);
}
}
- if (!ok)
- return ctx->engine()->throwTypeError(QStringLiteral("Cyclic __proto__ value"));
- return Encode::undefined();
+ if (!ok) {
+ scope.result = scope.engine->throwTypeError(QStringLiteral("Cyclic __proto__ value"));
+ return;
+ }
+ RETURN_UNDEFINED();
}
void ObjectPrototype::toPropertyDescriptor(ExecutionEngine *engine, const Value &v, Property *desc, PropertyAttributes *attrs)
diff --git a/src/qml/jsruntime/qv4objectproto_p.h b/src/qml/jsruntime/qv4objectproto_p.h
index e3d85782d5..1db8615511 100644
--- a/src/qml/jsruntime/qv4objectproto_p.h
+++ b/src/qml/jsruntime/qv4objectproto_p.h
@@ -78,32 +78,32 @@ struct ObjectPrototype: Object
{
void init(ExecutionEngine *engine, Object *ctor);
- static ReturnedValue method_getPrototypeOf(CallContext *ctx);
- static ReturnedValue method_getOwnPropertyDescriptor(CallContext *ctx);
- static ReturnedValue method_getOwnPropertyNames(CallContext *context);
- static ReturnedValue method_create(CallContext *ctx);
- static ReturnedValue method_defineProperty(CallContext *ctx);
- static ReturnedValue method_defineProperties(CallContext *ctx);
- static ReturnedValue method_seal(CallContext *ctx);
- static ReturnedValue method_freeze(CallContext *ctx);
- static ReturnedValue method_preventExtensions(CallContext *ctx);
- static ReturnedValue method_isSealed(CallContext *ctx);
- static ReturnedValue method_isFrozen(CallContext *ctx);
- static ReturnedValue method_isExtensible(CallContext *ctx);
- static ReturnedValue method_keys(CallContext *ctx);
-
- static ReturnedValue method_toString(CallContext *ctx);
- static ReturnedValue method_toLocaleString(CallContext *ctx);
- static ReturnedValue method_valueOf(CallContext *ctx);
- static ReturnedValue method_hasOwnProperty(CallContext *ctx);
- static ReturnedValue method_isPrototypeOf(CallContext *ctx);
- static ReturnedValue method_propertyIsEnumerable(CallContext *ctx);
-
- static ReturnedValue method_defineGetter(CallContext *ctx);
- static ReturnedValue method_defineSetter(CallContext *ctx);
-
- static ReturnedValue method_get_proto(CallContext *ctx);
- static ReturnedValue method_set_proto(CallContext *ctx);
+ static void method_getPrototypeOf(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getOwnPropertyDescriptor(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_getOwnPropertyNames(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_create(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_defineProperty(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_defineProperties(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_seal(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_freeze(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_preventExtensions(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_isSealed(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_isFrozen(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_isExtensible(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_keys(const BuiltinFunction *, Scope &scope, CallData *callData);
+
+ static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_hasOwnProperty(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_isPrototypeOf(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_propertyIsEnumerable(const BuiltinFunction *, Scope &scope, CallData *callData);
+
+ static void method_defineGetter(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_defineSetter(const BuiltinFunction *, Scope &scope, CallData *callData);
+
+ static void method_get_proto(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_set_proto(const BuiltinFunction *, Scope &scope, CallData *callData);
static void toPropertyDescriptor(ExecutionEngine *engine, const Value &v, Property *desc, PropertyAttributes *attrs);
static ReturnedValue fromPropertyDescriptor(ExecutionEngine *engine, const Property *desc, PropertyAttributes attrs);
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index 77dbb18b50..7260e71fab 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -826,40 +826,39 @@ struct QObjectSlotDispatcher : public QtPrivate::QSlotObjectBase
} // namespace QV4
-ReturnedValue QObjectWrapper::method_connect(CallContext *ctx)
+void QObjectWrapper::method_connect(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() == 0)
- V4THROW_ERROR("Function.prototype.connect: no arguments given");
+ if (callData->argc == 0)
+ THROW_GENERIC_ERROR("Function.prototype.connect: no arguments given");
- QPair<QObject *, int> signalInfo = extractQtSignal(ctx->thisObject());
+ QPair<QObject *, int> signalInfo = extractQtSignal(callData->thisObject);
QObject *signalObject = signalInfo.first;
int signalIndex = signalInfo.second; // in method range, not signal range!
if (signalIndex < 0)
- V4THROW_ERROR("Function.prototype.connect: this object is not a signal");
+ THROW_GENERIC_ERROR("Function.prototype.connect: this object is not a signal");
if (!signalObject)
- V4THROW_ERROR("Function.prototype.connect: cannot connect to deleted QObject");
+ THROW_GENERIC_ERROR("Function.prototype.connect: cannot connect to deleted QObject");
if (signalObject->metaObject()->method(signalIndex).methodType() != QMetaMethod::Signal)
- V4THROW_ERROR("Function.prototype.connect: this object is not a signal");
+ THROW_GENERIC_ERROR("Function.prototype.connect: this object is not a signal");
- QV4::Scope scope(ctx);
QV4::ScopedFunctionObject f(scope);
QV4::ScopedValue thisObject (scope, QV4::Encode::undefined());
- if (ctx->argc() == 1) {
- f = ctx->args()[0];
- } else if (ctx->argc() >= 2) {
- thisObject = ctx->args()[0];
- f = ctx->args()[1];
+ if (callData->argc == 1) {
+ f = callData->args[0];
+ } else if (callData->argc >= 2) {
+ thisObject = callData->args[0];
+ f = callData->args[1];
}
if (!f)
- V4THROW_ERROR("Function.prototype.connect: target is not a function");
+ THROW_GENERIC_ERROR("Function.prototype.connect: target is not a function");
if (!thisObject->isUndefined() && !thisObject->isObject())
- V4THROW_ERROR("Function.prototype.connect: target this is not an object");
+ THROW_GENERIC_ERROR("Function.prototype.connect: target this is not an object");
QV4::QObjectSlotDispatcher *slot = new QV4::QObjectSlotDispatcher;
slot->signalIndex = signalIndex;
@@ -874,49 +873,47 @@ ReturnedValue QObjectWrapper::method_connect(CallContext *ctx)
}
QObjectPrivate::connect(signalObject, signalIndex, slot, Qt::AutoConnection);
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
-ReturnedValue QObjectWrapper::method_disconnect(CallContext *ctx)
+void QObjectWrapper::method_disconnect(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() == 0)
- V4THROW_ERROR("Function.prototype.disconnect: no arguments given");
-
- QV4::Scope scope(ctx);
+ if (callData->argc == 0)
+ THROW_GENERIC_ERROR("Function.prototype.disconnect: no arguments given");
- QPair<QObject *, int> signalInfo = extractQtSignal(ctx->thisObject());
+ QPair<QObject *, int> signalInfo = extractQtSignal(callData->thisObject);
QObject *signalObject = signalInfo.first;
int signalIndex = signalInfo.second;
if (signalIndex == -1)
- V4THROW_ERROR("Function.prototype.disconnect: this object is not a signal");
+ THROW_GENERIC_ERROR("Function.prototype.disconnect: this object is not a signal");
if (!signalObject)
- V4THROW_ERROR("Function.prototype.disconnect: cannot disconnect from deleted QObject");
+ THROW_GENERIC_ERROR("Function.prototype.disconnect: cannot disconnect from deleted QObject");
if (signalIndex < 0 || signalObject->metaObject()->method(signalIndex).methodType() != QMetaMethod::Signal)
- V4THROW_ERROR("Function.prototype.disconnect: this object is not a signal");
+ THROW_GENERIC_ERROR("Function.prototype.disconnect: this object is not a signal");
QV4::ScopedFunctionObject functionValue(scope);
QV4::ScopedValue functionThisValue(scope, QV4::Encode::undefined());
- if (ctx->argc() == 1) {
- functionValue = ctx->args()[0];
- } else if (ctx->argc() >= 2) {
- functionThisValue = ctx->args()[0];
- functionValue = ctx->args()[1];
+ if (callData->argc == 1) {
+ functionValue = callData->args[0];
+ } else if (callData->argc >= 2) {
+ functionThisValue = callData->args[0];
+ functionValue = callData->args[1];
}
if (!functionValue)
- V4THROW_ERROR("Function.prototype.disconnect: target is not a function");
+ THROW_GENERIC_ERROR("Function.prototype.disconnect: target is not a function");
if (!functionThisValue->isUndefined() && !functionThisValue->isObject())
- V4THROW_ERROR("Function.prototype.disconnect: target this is not an object");
+ THROW_GENERIC_ERROR("Function.prototype.disconnect: target this is not an object");
QPair<QObject *, int> functionData = QObjectMethod::extractQtMethod(functionValue);
void *a[] = {
- ctx->d()->engine,
+ scope.engine,
functionValue.ptr,
functionThisValue.ptr,
functionData.first,
@@ -925,7 +922,7 @@ ReturnedValue QObjectWrapper::method_disconnect(CallContext *ctx)
QObjectPrivate::disconnect(signalObject, signalIndex, reinterpret_cast<void**>(&a));
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
static void markChildQObjectsRecursively(QObject *parent, QV4::ExecutionEngine *e)
diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h
index c7c4f4dd77..b09e06cec5 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper_p.h
+++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h
@@ -197,8 +197,8 @@ protected:
static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes);
static void markObjects(Heap::Base *that, QV4::ExecutionEngine *e);
- static ReturnedValue method_connect(CallContext *ctx);
- static ReturnedValue method_disconnect(CallContext *ctx);
+ static void method_connect(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_disconnect(const BuiltinFunction *, Scope &scope, CallData *callData);
private:
Q_NEVER_INLINE static ReturnedValue wrap_slowPath(ExecutionEngine *engine, QObject *object);
diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp
index 41d8010fef..40682aaa4b 100644
--- a/src/qml/jsruntime/qv4regexpobject.cpp
+++ b/src/qml/jsruntime/qv4regexpobject.cpp
@@ -349,34 +349,33 @@ void RegExpPrototype::init(ExecutionEngine *engine, Object *constructor)
defineDefaultProperty(QStringLiteral("compile"), method_compile, 2);
}
-ReturnedValue RegExpPrototype::method_exec(CallContext *ctx)
+void RegExpPrototype::method_exec(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<RegExpObject> r(scope, ctx->thisObject().as<RegExpObject>());
+ Scoped<RegExpObject> r(scope, callData->thisObject.as<RegExpObject>());
if (!r)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- ScopedValue arg(scope, ctx->argument(0));
+ ScopedValue arg(scope, callData->argument(0));
ScopedString str(scope, arg->toString(scope.engine));
if (scope.hasException())
- return Encode::undefined();
+ RETURN_UNDEFINED();
QString s = str->toQString();
int offset = r->global() ? r->lastIndexProperty()->toInt32() : 0;
if (offset < 0 || offset > s.length()) {
*r->lastIndexProperty() = Primitive::fromInt32(0);
- return Encode::null();
+ RETURN_RESULT(Encode::null());
}
uint* matchOffsets = (uint*)alloca(r->value()->captureCount() * 2 * sizeof(uint));
const int result = Scoped<RegExp>(scope, r->value())->match(s, offset, matchOffsets);
- Scoped<RegExpCtor> regExpCtor(scope, ctx->d()->engine->regExpCtor());
+ Scoped<RegExpCtor> regExpCtor(scope, scope.engine->regExpCtor());
regExpCtor->d()->clearLastMatch();
if (result == -1) {
*r->lastIndexProperty() = Primitive::fromInt32(0);
- return Encode::null();
+ RETURN_RESULT(Encode::null());
}
// fill in result data
@@ -387,7 +386,7 @@ ReturnedValue RegExpPrototype::method_exec(CallContext *ctx)
for (int i = 0; i < len; ++i) {
int start = matchOffsets[i * 2];
int end = matchOffsets[i * 2 + 1];
- v = (start != -1) ? ctx->d()->engine->newString(s.mid(start, end - start))->asReturnedValue() : Encode::undefined();
+ v = (start != -1) ? scope.engine->newString(s.mid(start, end - start))->asReturnedValue() : Encode::undefined();
array->arrayPut(i, v);
}
array->setArrayLengthUnchecked(len);
@@ -403,84 +402,75 @@ ReturnedValue RegExpPrototype::method_exec(CallContext *ctx)
if (r->global())
*r->lastIndexProperty() = Primitive::fromInt32(matchOffsets[1]);
- return array.asReturnedValue();
+ scope.result = array;
}
-ReturnedValue RegExpPrototype::method_test(CallContext *ctx)
+void RegExpPrototype::method_test(const BuiltinFunction *b, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedValue r(scope, method_exec(ctx));
- return Encode(!r->isNull());
+ method_exec(b, scope, callData);
+ scope.result = Encode(!scope.result.isNull());
}
-ReturnedValue RegExpPrototype::method_toString(CallContext *ctx)
+void RegExpPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<RegExpObject> r(scope, ctx->thisObject().as<RegExpObject>());
+ Scoped<RegExpObject> r(scope, callData->thisObject.as<RegExpObject>());
if (!r)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- return ctx->d()->engine->newString(r->toString())->asReturnedValue();
+ scope.result = scope.engine->newString(r->toString());
}
-ReturnedValue RegExpPrototype::method_compile(CallContext *ctx)
+void RegExpPrototype::method_compile(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<RegExpObject> r(scope, ctx->thisObject().as<RegExpObject>());
+ Scoped<RegExpObject> r(scope, callData->thisObject.as<RegExpObject>());
if (!r)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- ScopedCallData callData(scope, ctx->argc());
- memcpy(callData->args, ctx->args(), ctx->argc()*sizeof(Value));
+ ScopedCallData cData(scope, callData->argc);
+ memcpy(cData->args, callData->args, callData->argc*sizeof(Value));
- ctx->d()->engine->regExpCtor()->as<FunctionObject>()->construct(scope, callData);
+ scope.engine->regExpCtor()->as<FunctionObject>()->construct(scope, cData);
Scoped<RegExpObject> re(scope, scope.result.asReturnedValue());
r->d()->value = re->value();
r->d()->global = re->global();
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
template <int index>
-ReturnedValue RegExpPrototype::method_get_lastMatch_n(CallContext *ctx)
+void RegExpPrototype::method_get_lastMatch_n(const BuiltinFunction *, Scope &scope, CallData *)
{
- Scope scope(ctx);
- ScopedArrayObject lastMatch(scope, static_cast<RegExpCtor*>(ctx->d()->engine->regExpCtor())->lastMatch());
- ScopedValue result(scope, lastMatch ? lastMatch->getIndexed(index) : Encode::undefined());
- if (result->isUndefined())
- return ctx->d()->engine->newString()->asReturnedValue();
- return result->asReturnedValue();
+ ScopedArrayObject lastMatch(scope, static_cast<RegExpCtor*>(scope.engine->regExpCtor())->lastMatch());
+ scope.result = lastMatch ? lastMatch->getIndexed(index) : Encode::undefined();
+ if (scope.result.isUndefined())
+ scope.result = scope.engine->newString();
}
-ReturnedValue RegExpPrototype::method_get_lastParen(CallContext *ctx)
+void RegExpPrototype::method_get_lastParen(const BuiltinFunction *, Scope &scope, CallData *)
{
- Scope scope(ctx);
- ScopedArrayObject lastMatch(scope, static_cast<RegExpCtor*>(ctx->d()->engine->regExpCtor())->lastMatch());
- ScopedValue result(scope, lastMatch ? lastMatch->getIndexed(lastMatch->getLength() - 1) : Encode::undefined());
- if (result->isUndefined())
- return ctx->d()->engine->newString()->asReturnedValue();
- return result->asReturnedValue();
+ ScopedArrayObject lastMatch(scope, static_cast<RegExpCtor*>(scope.engine->regExpCtor())->lastMatch());
+ scope.result = lastMatch ? lastMatch->getIndexed(lastMatch->getLength() - 1) : Encode::undefined();
+ if (scope.result.isUndefined())
+ scope.result = scope.engine->newString();
}
-ReturnedValue RegExpPrototype::method_get_input(CallContext *ctx)
+void RegExpPrototype::method_get_input(const BuiltinFunction *, Scope &scope, CallData *)
{
- return static_cast<RegExpCtor*>(ctx->d()->engine->regExpCtor())->lastInput()->asReturnedValue();
+ scope.result = static_cast<RegExpCtor*>(scope.engine->regExpCtor())->lastInput();
}
-ReturnedValue RegExpPrototype::method_get_leftContext(CallContext *ctx)
+void RegExpPrototype::method_get_leftContext(const BuiltinFunction *, Scope &scope, CallData *)
{
- Scope scope(ctx);
- Scoped<RegExpCtor> regExpCtor(scope, ctx->d()->engine->regExpCtor());
+ Scoped<RegExpCtor> regExpCtor(scope, scope.engine->regExpCtor());
QString lastInput = regExpCtor->lastInput()->toQString();
- return ctx->d()->engine->newString(lastInput.left(regExpCtor->lastMatchStart()))->asReturnedValue();
+ scope.result = scope.engine->newString(lastInput.left(regExpCtor->lastMatchStart()));
}
-ReturnedValue RegExpPrototype::method_get_rightContext(CallContext *ctx)
+void RegExpPrototype::method_get_rightContext(const BuiltinFunction *, Scope &scope, CallData *)
{
- Scope scope(ctx);
- Scoped<RegExpCtor> regExpCtor(scope, ctx->d()->engine->regExpCtor());
+ Scoped<RegExpCtor> regExpCtor(scope, scope.engine->regExpCtor());
QString lastInput = regExpCtor->lastInput()->toQString();
- return ctx->d()->engine->newString(lastInput.mid(regExpCtor->lastMatchEnd()))->asReturnedValue();
+ scope.result = scope.engine->newString(lastInput.mid(regExpCtor->lastMatchEnd()));
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4regexpobject_p.h b/src/qml/jsruntime/qv4regexpobject_p.h
index 2c82cfdfd1..c0c7dfa78a 100644
--- a/src/qml/jsruntime/qv4regexpobject_p.h
+++ b/src/qml/jsruntime/qv4regexpobject_p.h
@@ -149,17 +149,17 @@ struct RegExpPrototype: RegExpObject
{
void init(ExecutionEngine *engine, Object *ctor);
- static ReturnedValue method_exec(CallContext *ctx);
- static ReturnedValue method_test(CallContext *ctx);
- static ReturnedValue method_toString(CallContext *ctx);
- static ReturnedValue method_compile(CallContext *ctx);
+ static void method_exec(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_test(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_compile(const BuiltinFunction *, Scope &scope, CallData *callData);
template <int index>
- static ReturnedValue method_get_lastMatch_n(CallContext *ctx);
- static ReturnedValue method_get_lastParen(CallContext *ctx);
- static ReturnedValue method_get_input(CallContext *ctx);
- static ReturnedValue method_get_leftContext(CallContext *ctx);
- static ReturnedValue method_get_rightContext(CallContext *ctx);
+ static void method_get_lastMatch_n(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_get_lastParen(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_get_input(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_get_leftContext(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_get_rightContext(const BuiltinFunction *, Scope &scope, CallData *callData);
};
}
diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h
index 4e627e003f..6775028272 100644
--- a/src/qml/jsruntime/qv4scopedvalue_p.h
+++ b/src/qml/jsruntime/qv4scopedvalue_p.h
@@ -68,6 +68,38 @@ namespace QV4 {
struct ScopedValue;
+#define CHECK_EXCEPTION() \
+ do { \
+ if (scope.hasException()) { \
+ scope.result = QV4::Encode::undefined(); \
+ return; \
+ } \
+ } while (false)
+
+#define RETURN_UNDEFINED() \
+ do { \
+ scope.result = QV4::Encode::undefined(); \
+ return; \
+ } while (false)
+
+#define RETURN_RESULT(r) \
+ do { \
+ scope.result = r; \
+ return; \
+ } while (false)
+
+#define THROW_TYPE_ERROR() \
+ do { \
+ scope.result = scope.engine->throwTypeError(); \
+ return; \
+ } while (false)
+
+#define THROW_GENERIC_ERROR(str) \
+ do { \
+ scope.result = scope.engine->throwError(QString::fromUtf8(str)); \
+ return; \
+ } while (false)
+
struct Scope {
inline Scope(ExecutionContext *ctx)
: engine(ctx->d()->engine)
diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp
index 58da7b9f68..8ce10e326d 100644
--- a/src/qml/jsruntime/qv4sequenceobject.cpp
+++ b/src/qml/jsruntime/qv4sequenceobject.cpp
@@ -404,28 +404,28 @@ public:
struct CompareFunctor
{
- CompareFunctor(QV4::ExecutionContext *ctx, const QV4::Value &compareFn)
- : m_ctx(ctx), m_compareFn(&compareFn)
+ CompareFunctor(QV4::ExecutionEngine *v4, const QV4::Value &compareFn)
+ : m_v4(v4), m_compareFn(&compareFn)
{}
bool operator()(typename Container::value_type lhs, typename Container::value_type rhs)
{
- QV4::Scope scope(m_ctx);
+ QV4::Scope scope(m_v4);
ScopedObject compare(scope, m_compareFn);
ScopedCallData callData(scope, 2);
- callData->args[0] = convertElementToValue(this->m_ctx->d()->engine, lhs);
- callData->args[1] = convertElementToValue(this->m_ctx->d()->engine, rhs);
- callData->thisObject = this->m_ctx->d()->engine->globalObject;
+ callData->args[0] = convertElementToValue(m_v4, lhs);
+ callData->args[1] = convertElementToValue(m_v4, rhs);
+ callData->thisObject = m_v4->globalObject;
compare->call(scope, callData);
return scope.result.toNumber() < 0;
}
private:
- QV4::ExecutionContext *m_ctx;
+ QV4::ExecutionEngine *m_v4;
const QV4::Value *m_compareFn;
};
- void sort(QV4::CallContext *ctx)
+ void sort(const BuiltinFunction *, Scope &scope, CallData *callData)
{
if (d()->isReference) {
if (!d()->object)
@@ -433,9 +433,8 @@ public:
loadReference();
}
- QV4::Scope scope(ctx);
- if (ctx->argc() == 1 && ctx->args()[0].as<FunctionObject>()) {
- CompareFunctor cf(ctx, ctx->args()[0]);
+ if (callData->argc == 1 && callData->args[0].as<FunctionObject>()) {
+ CompareFunctor cf(scope.engine, callData->args[0]);
std::sort(d()->container->begin(), d()->container->end(), cf);
} else {
DefaultCompareFunctor cf;
@@ -446,45 +445,43 @@ public:
storeReference();
}
- static QV4::ReturnedValue method_get_length(QV4::CallContext *ctx)
+ static void method_get_length(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQmlSequence<Container> > This(scope, ctx->thisObject().as<QQmlSequence<Container> >());
+ QV4::Scoped<QQmlSequence<Container> > This(scope, callData->thisObject.as<QQmlSequence<Container> >());
if (!This)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
if (This->d()->isReference) {
if (!This->d()->object)
- return QV4::Encode(0);
+ RETURN_RESULT(Encode(0));
This->loadReference();
}
- return QV4::Encode(This->d()->container->count());
+ RETURN_RESULT(Encode(This->d()->container->count()));
}
- static QV4::ReturnedValue method_set_length(QV4::CallContext* ctx)
+ static void method_set_length(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQmlSequence<Container> > This(scope, ctx->thisObject().as<QQmlSequence<Container> >());
+ QV4::Scoped<QQmlSequence<Container> > This(scope, callData->thisObject.as<QQmlSequence<Container> >());
if (!This)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- quint32 newLength = ctx->args()[0].toUInt32();
+ quint32 newLength = callData->args[0].toUInt32();
/* Qt containers have int (rather than uint) allowable indexes. */
if (newLength > INT_MAX) {
generateWarning(scope.engine, QLatin1String("Index out of range during length set"));
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
/* Read the sequence from the QObject property if we're a reference */
if (This->d()->isReference) {
if (!This->d()->object)
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
This->loadReference();
}
/* Determine whether we need to modify the sequence */
qint32 newCount = static_cast<qint32>(newLength);
qint32 count = This->d()->container->count();
if (newCount == count) {
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
} else if (newCount > count) {
/* according to ECMA262r3 we need to insert */
/* undefined values increasing length to newLength. */
@@ -506,7 +503,7 @@ public:
/* write back. already checked that object is non-null, so skip that check here. */
This->storeReference();
}
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
QVariant toVariant() const
@@ -625,26 +622,25 @@ void SequencePrototype::init()
}
#undef REGISTER_QML_SEQUENCE_METATYPE
-QV4::ReturnedValue SequencePrototype::method_sort(QV4::CallContext *ctx)
+void SequencePrototype::method_sort(const BuiltinFunction *b, Scope &scope, CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::ScopedObject o(scope, ctx->thisObject());
+ QV4::ScopedObject o(scope, callData->thisObject);
if (!o || !o->isListType())
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- if (ctx->argc() >= 2)
- return o.asReturnedValue();
+ if (callData->argc >= 2)
+ RETURN_RESULT(o);
#define CALL_SORT(SequenceElementType, SequenceElementTypeName, SequenceType, DefaultValue) \
if (QQml##SequenceElementTypeName##List *s = o->as<QQml##SequenceElementTypeName##List>()) { \
- s->sort(ctx); \
+ s->sort(b, scope, callData); \
} else
FOREACH_QML_SEQUENCE_TYPE(CALL_SORT)
#undef CALL_SORT
{}
- return o.asReturnedValue();
+ RETURN_RESULT(o);
}
#define IS_SEQUENCE(unused1, unused2, SequenceType, unused3) \
diff --git a/src/qml/jsruntime/qv4sequenceobject_p.h b/src/qml/jsruntime/qv4sequenceobject_p.h
index c0416ad639..6f96b9f760 100644
--- a/src/qml/jsruntime/qv4sequenceobject_p.h
+++ b/src/qml/jsruntime/qv4sequenceobject_p.h
@@ -67,12 +67,12 @@ struct SequencePrototype : public QV4::Object
{
void init();
- static ReturnedValue method_valueOf(QV4::CallContext *ctx)
+ static void method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- return ctx->thisObject().toString(ctx->engine())->asReturnedValue();
+ scope.result = callData->thisObject.toString(scope.engine);
}
- static ReturnedValue method_sort(QV4::CallContext *ctx);
+ static void method_sort(const BuiltinFunction *, Scope &scope, CallData *callData);
static bool isSequenceType(int sequenceTypeId);
static ReturnedValue newSequence(QV4::ExecutionEngine *engine, int sequenceTypeId, QObject *object, int propertyIndex, bool *succeeded);
diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp
index 6fbf1c3c85..3c6a24e035 100644
--- a/src/qml/jsruntime/qv4stringobject.cpp
+++ b/src/qml/jsruntime/qv4stringobject.cpp
@@ -214,10 +214,9 @@ void StringPrototype::init(ExecutionEngine *engine, Object *ctor)
defineDefaultProperty(QStringLiteral("trim"), method_trim);
}
-static QString getThisString(ExecutionContext *ctx)
+static QString getThisString(Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- ScopedValue t(scope, ctx->thisObject());
+ ScopedValue t(scope, callData->thisObject);
if (String *s = t->stringValue())
return s->toQString();
if (StringObject *thisString = t->as<StringObject>())
@@ -229,158 +228,146 @@ static QString getThisString(ExecutionContext *ctx)
return t->toQString();
}
-ReturnedValue StringPrototype::method_toString(CallContext *context)
+void StringPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (context->thisObject().isString())
- return context->thisObject().asReturnedValue();
+ if (callData->thisObject.isString())
+ RETURN_RESULT(callData->thisObject);
- StringObject *o = context->thisObject().as<StringObject>();
+ StringObject *o = callData->thisObject.as<StringObject>();
if (!o)
- return context->engine()->throwTypeError();
- return Encode(o->d()->string);
+ THROW_TYPE_ERROR();
+ scope.result = o->d()->string;
}
-ReturnedValue StringPrototype::method_charAt(CallContext *context)
+void StringPrototype::method_charAt(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- const QString str = getThisString(context);
- if (context->d()->engine->hasException)
- return Encode::undefined();
+ const QString str = getThisString(scope, callData);
+ CHECK_EXCEPTION();
int pos = 0;
- if (context->argc() > 0)
- pos = (int) context->args()[0].toInteger();
+ if (callData->argc > 0)
+ pos = (int) callData->args[0].toInteger();
QString result;
if (pos >= 0 && pos < str.length())
result += str.at(pos);
- return context->d()->engine->newString(result)->asReturnedValue();
+ scope.result = scope.engine->newString(result);
}
-ReturnedValue StringPrototype::method_charCodeAt(CallContext *context)
+void StringPrototype::method_charCodeAt(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- const QString str = getThisString(context);
- if (context->d()->engine->hasException)
- return Encode::undefined();
+ const QString str = getThisString(scope, callData);
+ CHECK_EXCEPTION();
int pos = 0;
- if (context->argc() > 0)
- pos = (int) context->args()[0].toInteger();
+ if (callData->argc > 0)
+ pos = (int) callData->args[0].toInteger();
if (pos >= 0 && pos < str.length())
- return Encode(str.at(pos).unicode());
+ RETURN_RESULT(Encode(str.at(pos).unicode()));
- return Encode(qt_qnan());
+ scope.result = Encode(qt_qnan());
}
-ReturnedValue StringPrototype::method_concat(CallContext *context)
+void StringPrototype::method_concat(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(context);
-
- QString value = getThisString(context);
- if (scope.engine->hasException)
- return Encode::undefined();
+ QString value = getThisString(scope, callData);
+ CHECK_EXCEPTION();
ScopedString s(scope);
- for (int i = 0; i < context->argc(); ++i) {
- s = context->args()[i].toString(scope.engine);
- if (scope.hasException())
- return Encode::undefined();
+ for (int i = 0; i < callData->argc; ++i) {
+ s = callData->args[i].toString(scope.engine);
+ CHECK_EXCEPTION();
+
Q_ASSERT(s->isString());
value += s->toQString();
}
- return context->d()->engine->newString(value)->asReturnedValue();
+ scope.result = scope.engine->newString(value);
}
-ReturnedValue StringPrototype::method_endsWith(CallContext *context)
+void StringPrototype::method_endsWith(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QString value = getThisString(context);
- if (context->d()->engine->hasException)
- return Encode::undefined();
+ QString value = getThisString(scope, callData);
+ CHECK_EXCEPTION();
QString searchString;
- if (context->argc()) {
- if (context->args()[0].as<RegExpObject>())
- return context->engine()->throwTypeError();
- searchString = context->args()[0].toQString();
+ if (callData->argc) {
+ if (callData->args[0].as<RegExpObject>())
+ THROW_TYPE_ERROR();
+ searchString = callData->args[0].toQString();
}
int pos = value.length();
- if (context->argc() > 1)
- pos = (int) context->args()[1].toInteger();
+ if (callData->argc > 1)
+ pos = (int) callData->args[1].toInteger();
if (pos == value.length())
- return Encode(value.endsWith(searchString));
+ RETURN_RESULT(Encode(value.endsWith(searchString)));
QStringRef stringToSearch = value.leftRef(pos);
- return Encode(stringToSearch.endsWith(searchString));
+ scope.result = Encode(stringToSearch.endsWith(searchString));
}
-ReturnedValue StringPrototype::method_indexOf(CallContext *context)
+void StringPrototype::method_indexOf(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QString value = getThisString(context);
- if (context->d()->engine->hasException)
- return Encode::undefined();
+ QString value = getThisString(scope, callData);
+ CHECK_EXCEPTION();
QString searchString;
- if (context->argc())
- searchString = context->args()[0].toQString();
+ if (callData->argc)
+ searchString = callData->args[0].toQString();
int pos = 0;
- if (context->argc() > 1)
- pos = (int) context->args()[1].toInteger();
+ if (callData->argc > 1)
+ pos = (int) callData->args[1].toInteger();
int index = -1;
if (! value.isEmpty())
index = value.indexOf(searchString, qMin(qMax(pos, 0), value.length()));
- return Encode(index);
+ scope.result = Encode(index);
}
-ReturnedValue StringPrototype::method_includes(CallContext *context)
+void StringPrototype::method_includes(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QString value = getThisString(context);
- if (context->d()->engine->hasException)
- return Encode::undefined();
+ QString value = getThisString(scope, callData);
+ CHECK_EXCEPTION();
QString searchString;
- if (context->argc()) {
- if (context->args()[0].as<RegExpObject>())
- return context->engine()->throwTypeError();
- searchString = context->args()[0].toQString();
+ if (callData->argc) {
+ if (callData->args[0].as<RegExpObject>())
+ THROW_TYPE_ERROR();
+ searchString = callData->args[0].toQString();
}
int pos = 0;
- if (context->argc() > 1) {
- Scope scope(context);
- ScopedValue posArg(scope, context->argument(1));
+ if (callData->argc > 1) {
+ ScopedValue posArg(scope, callData->argument(1));
pos = (int) posArg->toInteger();
if (!posArg->isInteger() && posArg->isNumber() && qIsInf(posArg->toNumber()))
pos = value.length();
}
if (pos == 0)
- return Encode(value.contains(searchString));
+ RETURN_RESULT(Encode(value.contains(searchString)));
QStringRef stringToSearch = value.midRef(pos);
- return Encode(stringToSearch.contains(searchString));
+ scope.result = Encode(stringToSearch.contains(searchString));
}
-ReturnedValue StringPrototype::method_lastIndexOf(CallContext *context)
+void StringPrototype::method_lastIndexOf(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(context);
-
- const QString value = getThisString(context);
- if (scope.engine->hasException)
- return Encode::undefined();
+ const QString value = getThisString(scope, callData);
+ CHECK_EXCEPTION();
QString searchString;
- if (context->argc())
- searchString = context->args()[0].toQString();
+ if (callData->argc)
+ searchString = callData->args[0].toQString();
- ScopedValue posArg(scope, context->argument(1));
+ ScopedValue posArg(scope, callData->argument(1));
double position = RuntimeHelpers::toNumber(posArg);
if (std::isnan(position))
position = +qInf();
@@ -391,43 +378,40 @@ ReturnedValue StringPrototype::method_lastIndexOf(CallContext *context)
if (!searchString.isEmpty() && pos == value.length())
--pos;
if (searchString.isNull() && pos == 0)
- return Encode(-1);
+ RETURN_RESULT(Encode(-1));
int index = value.lastIndexOf(searchString, pos);
- return Encode(index);
+ scope.result = Encode(index);
}
-ReturnedValue StringPrototype::method_localeCompare(CallContext *context)
+void StringPrototype::method_localeCompare(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(context);
- const QString value = getThisString(context);
- if (scope.engine->hasException)
- return Encode::undefined();
+ const QString value = getThisString(scope, callData);
+ CHECK_EXCEPTION();
- ScopedValue v(scope, context->argument(0));
+ ScopedValue v(scope, callData->argument(0));
const QString that = v->toQString();
- return Encode(QString::localeAwareCompare(value, that));
+ scope.result = Encode(QString::localeAwareCompare(value, that));
}
-ReturnedValue StringPrototype::method_match(CallContext *context)
+void StringPrototype::method_match(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (context->thisObject().isUndefined() || context->thisObject().isNull())
- return context->engine()->throwTypeError();
+ if (callData->thisObject.isUndefined() || callData->thisObject.isNull())
+ THROW_TYPE_ERROR();
- Scope scope(context);
- ScopedString s(scope, context->thisObject().toString(scope.engine));
+ ScopedString s(scope, callData->thisObject.toString(scope.engine));
- ScopedValue regexp(scope, context->argument(0));
+ ScopedValue regexp(scope, callData->argument(0));
Scoped<RegExpObject> rx(scope, regexp);
if (!rx) {
ScopedCallData callData(scope, 1);
callData->args[0] = regexp;
- context->d()->engine->regExpCtor()->construct(scope, callData);
+ scope.engine->regExpCtor()->construct(scope, callData);
rx = scope.result.asReturnedValue();
}
if (!rx)
// ### CHECK
- return context->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
bool global = rx->global();
@@ -435,24 +419,24 @@ ReturnedValue StringPrototype::method_match(CallContext *context)
ScopedString execString(scope, scope.engine->newString(QStringLiteral("exec")));
ScopedFunctionObject exec(scope, scope.engine->regExpPrototype()->get(execString));
- ScopedCallData callData(scope, 1);
- callData->thisObject = rx;
- callData->args[0] = s;
+ ScopedCallData cData(scope, 1);
+ cData->thisObject = rx;
+ cData->args[0] = s;
if (!global) {
- exec->call(scope, callData);
- return scope.result.asReturnedValue();
+ exec->call(scope, cData);
+ return;
}
- ScopedString lastIndex(scope, context->d()->engine->newString(QStringLiteral("lastIndex")));
+ ScopedString lastIndex(scope, scope.engine->newString(QStringLiteral("lastIndex")));
rx->put(lastIndex, ScopedValue(scope, Primitive::fromInt32(0)));
- ScopedArrayObject a(scope, context->d()->engine->newArrayObject());
+ ScopedArrayObject a(scope, scope.engine->newArrayObject());
double previousLastIndex = 0;
uint n = 0;
ScopedValue matchStr(scope);
ScopedValue index(scope);
while (1) {
- exec->call(scope, callData);
+ exec->call(scope, cData);
if (scope.result.isNull())
break;
assert(scope.result.isObject());
@@ -469,10 +453,9 @@ ReturnedValue StringPrototype::method_match(CallContext *context)
++n;
}
if (!n)
- return Encode::null();
-
- return a.asReturnedValue();
-
+ scope.result = Encode::null();
+ else
+ scope.result = a;
}
static void appendReplacementString(QString *result, const QString &input, const QString& replaceValue, uint* matchOffsets, int captureCount)
@@ -521,14 +504,13 @@ static void appendReplacementString(QString *result, const QString &input, const
}
}
-ReturnedValue StringPrototype::method_replace(CallContext *ctx)
+void StringPrototype::method_replace(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
QString string;
- if (StringObject *thisString = ctx->thisObject().as<StringObject>())
+ if (StringObject *thisString = callData->thisObject.as<StringObject>())
string = thisString->d()->string->toQString();
else
- string = ctx->thisObject().toQString();
+ string = callData->thisObject.toQString();
int numCaptures = 0;
int numStringMatches = 0;
@@ -537,7 +519,7 @@ ReturnedValue StringPrototype::method_replace(CallContext *ctx)
uint _matchOffsets[64];
uint *matchOffsets = _matchOffsets;
- ScopedValue searchValue(scope, ctx->argument(0));
+ ScopedValue searchValue(scope, callData->argument(0));
Scoped<RegExpObject> regExp(scope, searchValue);
if (regExp) {
uint offset = 0;
@@ -580,7 +562,7 @@ ReturnedValue StringPrototype::method_replace(CallContext *ctx)
}
QString result;
- ScopedValue replaceValue(scope, ctx->argument(1));
+ ScopedValue replaceValue(scope, callData->argument(1));
ScopedFunctionObject searchCallback(scope, replaceValue);
if (!!searchCallback) {
result.reserve(string.length() + 10*numStringMatches);
@@ -595,14 +577,14 @@ ReturnedValue StringPrototype::method_replace(CallContext *ctx)
uint end = matchOffsets[idx + 1];
entry = Primitive::undefinedValue();
if (start != JSC::Yarr::offsetNoMatch && end != JSC::Yarr::offsetNoMatch)
- entry = ctx->d()->engine->newString(string.mid(start, end - start));
+ entry = scope.engine->newString(string.mid(start, end - start));
callData->args[k] = entry;
}
uint matchStart = matchOffsets[i * numCaptures * 2];
Q_ASSERT(matchStart >= static_cast<uint>(lastEnd));
uint matchEnd = matchOffsets[i * numCaptures * 2 + 1];
callData->args[numCaptures] = Primitive::fromUInt32(matchStart);
- callData->args[numCaptures + 1] = ctx->d()->engine->newString(string);
+ callData->args[numCaptures + 1] = scope.engine->newString(string);
searchCallback->call(scope, callData);
result += string.midRef(lastEnd, matchStart - lastEnd);
@@ -632,23 +614,22 @@ ReturnedValue StringPrototype::method_replace(CallContext *ctx)
if (matchOffsets != _matchOffsets)
free(matchOffsets);
- return ctx->d()->engine->newString(result)->asReturnedValue();
+ scope.result = scope.engine->newString(result);
}
-ReturnedValue StringPrototype::method_search(CallContext *ctx)
+void StringPrototype::method_search(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- QString string = getThisString(ctx);
- scope.result = ctx->argument(0);
- if (scope.engine->hasException)
- return Encode::undefined();
+ QString string = getThisString(scope, callData);
+ scope.result = callData->argument(0);
+ CHECK_EXCEPTION();
+
Scoped<RegExpObject> regExp(scope, scope.result.as<RegExpObject>());
if (!regExp) {
ScopedCallData callData(scope, 1);
callData->args[0] = scope.result;
- ctx->d()->engine->regExpCtor()->construct(scope, callData);
- if (scope.engine->hasException)
- return Encode::undefined();
+ scope.engine->regExpCtor()->construct(scope, callData);
+ CHECK_EXCEPTION();
+
regExp = scope.result.as<RegExpObject>();
Q_ASSERT(regExp);
}
@@ -656,21 +637,21 @@ ReturnedValue StringPrototype::method_search(CallContext *ctx)
uint* matchOffsets = (uint*)alloca(regExp->value()->captureCount() * 2 * sizeof(uint));
uint result = re->match(string, /*offset*/0, matchOffsets);
if (result == JSC::Yarr::offsetNoMatch)
- return Encode(-1);
- return Encode(result);
+ scope.result = Encode(-1);
+ else
+ scope.result = Encode(result);
}
-ReturnedValue StringPrototype::method_slice(CallContext *ctx)
+void StringPrototype::method_slice(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- const QString text = getThisString(ctx);
- if (ctx->d()->engine->hasException)
- return Encode::undefined();
+ const QString text = getThisString(scope, callData);
+ CHECK_EXCEPTION();
const double length = text.length();
- double start = ctx->argc() ? ctx->args()[0].toInteger() : 0;
- double end = (ctx->argc() < 2 || ctx->args()[1].isUndefined())
- ? length : ctx->args()[1].toInteger();
+ double start = callData->argc ? callData->args[0].toInteger() : 0;
+ double end = (callData->argc < 2 || callData->args[1].isUndefined())
+ ? length : callData->args[1].toInteger();
if (start < 0)
start = qMax(length + start, 0.);
@@ -686,40 +667,38 @@ ReturnedValue StringPrototype::method_slice(CallContext *ctx)
const int intEnd = int(end);
int count = qMax(0, intEnd - intStart);
- return ctx->d()->engine->newString(text.mid(intStart, count))->asReturnedValue();
+ scope.result = scope.engine->newString(text.mid(intStart, count));
}
-ReturnedValue StringPrototype::method_split(CallContext *ctx)
+void StringPrototype::method_split(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- QString text = getThisString(ctx);
- if (scope.engine->hasException)
- return Encode::undefined();
+ QString text = getThisString(scope, callData);
+ CHECK_EXCEPTION();
- ScopedValue separatorValue(scope, ctx->argument(0));
- ScopedValue limitValue(scope, ctx->argument(1));
+ ScopedValue separatorValue(scope, callData->argument(0));
+ ScopedValue limitValue(scope, callData->argument(1));
- ScopedArrayObject array(scope, ctx->d()->engine->newArrayObject());
+ ScopedArrayObject array(scope, scope.engine->newArrayObject());
if (separatorValue->isUndefined()) {
if (limitValue->isUndefined()) {
- ScopedString s(scope, ctx->d()->engine->newString(text));
+ ScopedString s(scope, scope.engine->newString(text));
array->push_back(s);
- return array.asReturnedValue();
+ RETURN_RESULT(array);
}
- return ctx->d()->engine->newString(text.left(limitValue->toInteger()))->asReturnedValue();
+ RETURN_RESULT(scope.engine->newString(text.left(limitValue->toInteger())));
}
uint limit = limitValue->isUndefined() ? UINT_MAX : limitValue->toUInt32();
if (limit == 0)
- return array.asReturnedValue();
+ RETURN_RESULT(array);
Scoped<RegExpObject> re(scope, separatorValue);
if (re) {
if (re->value()->pattern->isEmpty()) {
re = (RegExpObject *)0;
- separatorValue = ctx->d()->engine->newString();
+ separatorValue = scope.engine->newString();
}
}
@@ -733,7 +712,7 @@ ReturnedValue StringPrototype::method_split(CallContext *ctx)
if (result == JSC::Yarr::offsetNoMatch)
break;
- array->push_back((s = ctx->d()->engine->newString(text.mid(offset, matchOffsets[0] - offset))));
+ array->push_back((s = scope.engine->newString(text.mid(offset, matchOffsets[0] - offset))));
offset = qMax(offset + 1, matchOffsets[1]);
if (array->getLength() >= limit)
@@ -742,72 +721,70 @@ ReturnedValue StringPrototype::method_split(CallContext *ctx)
for (int i = 1; i < re->value()->captureCount(); ++i) {
uint start = matchOffsets[i * 2];
uint end = matchOffsets[i * 2 + 1];
- array->push_back((s = ctx->d()->engine->newString(text.mid(start, end - start))));
+ array->push_back((s = scope.engine->newString(text.mid(start, end - start))));
if (array->getLength() >= limit)
break;
}
}
if (array->getLength() < limit)
- array->push_back((s = ctx->d()->engine->newString(text.mid(offset))));
+ array->push_back((s = scope.engine->newString(text.mid(offset))));
} else {
QString separator = separatorValue->toQString();
if (separator.isEmpty()) {
for (uint i = 0; i < qMin(limit, uint(text.length())); ++i)
- array->push_back((s = ctx->d()->engine->newString(text.mid(i, 1))));
- return array.asReturnedValue();
+ array->push_back((s = scope.engine->newString(text.mid(i, 1))));
+ RETURN_RESULT(array);
}
int start = 0;
int end;
while ((end = text.indexOf(separator, start)) != -1) {
- array->push_back((s = ctx->d()->engine->newString(text.mid(start, end - start))));
+ array->push_back((s = scope.engine->newString(text.mid(start, end - start))));
start = end + separator.size();
if (array->getLength() >= limit)
break;
}
if (array->getLength() < limit && start != -1)
- array->push_back((s = ctx->d()->engine->newString(text.mid(start))));
+ array->push_back((s = scope.engine->newString(text.mid(start))));
}
- return array.asReturnedValue();
+ RETURN_RESULT(array);
}
-ReturnedValue StringPrototype::method_startsWith(CallContext *context)
+void StringPrototype::method_startsWith(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QString value = getThisString(context);
- if (context->d()->engine->hasException)
- return Encode::undefined();
+ QString value = getThisString(scope, callData);
+ CHECK_EXCEPTION();
QString searchString;
- if (context->argc()) {
- if (context->args()[0].as<RegExpObject>())
- return context->engine()->throwTypeError();
- searchString = context->args()[0].toQString();
+ if (callData->argc) {
+ if (callData->args[0].as<RegExpObject>())
+ THROW_TYPE_ERROR();
+ searchString = callData->args[0].toQString();
}
int pos = 0;
- if (context->argc() > 1)
- pos = (int) context->args()[1].toInteger();
+ if (callData->argc > 1)
+ pos = (int) callData->args[1].toInteger();
if (pos == 0)
- return Encode(value.startsWith(searchString));
+ RETURN_RESULT(Encode(value.startsWith(searchString)));
QStringRef stringToSearch = value.midRef(pos);
- return Encode(stringToSearch.startsWith(searchString));
+ RETURN_RESULT(Encode(stringToSearch.startsWith(searchString)));
}
-ReturnedValue StringPrototype::method_substr(CallContext *context)
+void StringPrototype::method_substr(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- const QString value = getThisString(context);
- if (context->d()->engine->hasException)
- return Encode::undefined();
+ const QString value = getThisString(scope, callData);
+ CHECK_EXCEPTION();
double start = 0;
- if (context->argc() > 0)
- start = context->args()[0].toInteger();
+ if (callData->argc > 0)
+ start = callData->args[0].toInteger();
double length = +qInf();
- if (context->argc() > 1)
- length = context->args()[1].toInteger();
+ if (callData->argc > 1)
+ length = callData->args[1].toInteger();
double count = value.length();
if (start < 0)
@@ -817,24 +794,23 @@ ReturnedValue StringPrototype::method_substr(CallContext *context)
qint32 x = Primitive::toInt32(start);
qint32 y = Primitive::toInt32(length);
- return context->d()->engine->newString(value.mid(x, y))->asReturnedValue();
+ scope.result = scope.engine->newString(value.mid(x, y));
}
-ReturnedValue StringPrototype::method_substring(CallContext *context)
+void StringPrototype::method_substring(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QString value = getThisString(context);
- if (context->d()->engine->hasException)
- return Encode::undefined();
+ QString value = getThisString(scope, callData);
+ CHECK_EXCEPTION();
+
int length = value.length();
double start = 0;
double end = length;
- if (context->argc() > 0)
- start = context->args()[0].toInteger();
+ if (callData->argc > 0)
+ start = callData->args[0].toInteger();
- Scope scope(context);
- ScopedValue endValue(scope, context->argument(1));
+ ScopedValue endValue(scope, callData->argument(1));
if (!endValue->isUndefined())
end = endValue->toInteger();
@@ -858,51 +834,50 @@ ReturnedValue StringPrototype::method_substring(CallContext *context)
qint32 x = (int)start;
qint32 y = (int)(end - start);
- return context->d()->engine->newString(value.mid(x, y))->asReturnedValue();
+ scope.result = scope.engine->newString(value.mid(x, y));
}
-ReturnedValue StringPrototype::method_toLowerCase(CallContext *ctx)
+void StringPrototype::method_toLowerCase(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QString value = getThisString(ctx);
- if (ctx->d()->engine->hasException)
- return Encode::undefined();
- return ctx->d()->engine->newString(value.toLower())->asReturnedValue();
+ QString value = getThisString(scope, callData);
+ CHECK_EXCEPTION();
+
+ scope.result = scope.engine->newString(value.toLower());
}
-ReturnedValue StringPrototype::method_toLocaleLowerCase(CallContext *ctx)
+void StringPrototype::method_toLocaleLowerCase(const BuiltinFunction *b, Scope &scope, CallData *callData)
{
- return method_toLowerCase(ctx);
+ method_toLowerCase(b, scope, callData);
}
-ReturnedValue StringPrototype::method_toUpperCase(CallContext *ctx)
+void StringPrototype::method_toUpperCase(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QString value = getThisString(ctx);
- if (ctx->d()->engine->hasException)
- return Encode::undefined();
- return ctx->d()->engine->newString(value.toUpper())->asReturnedValue();
+ QString value = getThisString(scope, callData);
+ CHECK_EXCEPTION();
+
+ scope.result = scope.engine->newString(value.toUpper());
}
-ReturnedValue StringPrototype::method_toLocaleUpperCase(CallContext *ctx)
+void StringPrototype::method_toLocaleUpperCase(const BuiltinFunction *b, Scope &scope, CallData *callData)
{
- return method_toUpperCase(ctx);
+ return method_toUpperCase(b, scope, callData);
}
-ReturnedValue StringPrototype::method_fromCharCode(CallContext *context)
+void StringPrototype::method_fromCharCode(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QString str(context->argc(), Qt::Uninitialized);
+ QString str(callData->argc, Qt::Uninitialized);
QChar *ch = str.data();
- for (int i = 0; i < context->argc(); ++i) {
- *ch = QChar(context->args()[i].toUInt16());
+ for (int i = 0; i < callData->argc; ++i) {
+ *ch = QChar(callData->args[i].toUInt16());
++ch;
}
- return context->d()->engine->newString(str)->asReturnedValue();
+ scope.result = scope.engine->newString(str);
}
-ReturnedValue StringPrototype::method_trim(CallContext *ctx)
+void StringPrototype::method_trim(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QString s = getThisString(ctx);
- if (ctx->d()->engine->hasException)
- return Encode::undefined();
+ QString s = getThisString(scope, callData);
+ CHECK_EXCEPTION();
const QChar *chars = s.constData();
int start, end;
@@ -915,5 +890,5 @@ ReturnedValue StringPrototype::method_trim(CallContext *ctx)
break;
}
- return ctx->d()->engine->newString(QString(chars + start, end - start + 1))->asReturnedValue();
+ scope.result = scope.engine->newString(QString(chars + start, end - start + 1));
}
diff --git a/src/qml/jsruntime/qv4stringobject_p.h b/src/qml/jsruntime/qv4stringobject_p.h
index b9f9d44fe8..0ee7a6ece9 100644
--- a/src/qml/jsruntime/qv4stringobject_p.h
+++ b/src/qml/jsruntime/qv4stringobject_p.h
@@ -111,29 +111,29 @@ struct StringPrototype: StringObject
{
void init(ExecutionEngine *engine, Object *ctor);
- static ReturnedValue method_toString(CallContext *context);
- static ReturnedValue method_charAt(CallContext *context);
- static ReturnedValue method_charCodeAt(CallContext *context);
- static ReturnedValue method_concat(CallContext *context);
- static ReturnedValue method_endsWith(CallContext *ctx);
- static ReturnedValue method_indexOf(CallContext *context);
- static ReturnedValue method_includes(CallContext *context);
- static ReturnedValue method_lastIndexOf(CallContext *context);
- static ReturnedValue method_localeCompare(CallContext *context);
- static ReturnedValue method_match(CallContext *context);
- static ReturnedValue method_replace(CallContext *ctx);
- static ReturnedValue method_search(CallContext *ctx);
- static ReturnedValue method_slice(CallContext *ctx);
- static ReturnedValue method_split(CallContext *ctx);
- static ReturnedValue method_startsWith(CallContext *ctx);
- static ReturnedValue method_substr(CallContext *context);
- static ReturnedValue method_substring(CallContext *context);
- static ReturnedValue method_toLowerCase(CallContext *ctx);
- static ReturnedValue method_toLocaleLowerCase(CallContext *ctx);
- static ReturnedValue method_toUpperCase(CallContext *ctx);
- static ReturnedValue method_toLocaleUpperCase(CallContext *ctx);
- static ReturnedValue method_fromCharCode(CallContext *context);
- static ReturnedValue method_trim(CallContext *ctx);
+ static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_charAt(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_charCodeAt(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_concat(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_endsWith(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_indexOf(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_includes(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_lastIndexOf(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_localeCompare(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_match(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_replace(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_search(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_slice(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_split(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_startsWith(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_substr(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_substring(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toLowerCase(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toLocaleLowerCase(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toUpperCase(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toLocaleUpperCase(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_fromCharCode(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_trim(const BuiltinFunction *, Scope &scope, CallData *callData);
};
}
diff --git a/src/qml/jsruntime/qv4typedarray.cpp b/src/qml/jsruntime/qv4typedarray.cpp
index 009c573bf8..cecd1e6958 100644
--- a/src/qml/jsruntime/qv4typedarray.cpp
+++ b/src/qml/jsruntime/qv4typedarray.cpp
@@ -438,79 +438,74 @@ void TypedArrayPrototype::init(ExecutionEngine *engine, TypedArrayCtor *ctor)
defineDefaultProperty(QStringLiteral("subarray"), method_subarray, 0);
}
-ReturnedValue TypedArrayPrototype::method_get_buffer(CallContext *ctx)
+void TypedArrayPrototype::method_get_buffer(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<TypedArray> v(scope, ctx->thisObject());
+ Scoped<TypedArray> v(scope, callData->thisObject);
if (!v)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
- return Encode(v->d()->buffer->asReturnedValue());
+ scope.result = v->d()->buffer;
}
-ReturnedValue TypedArrayPrototype::method_get_byteLength(CallContext *ctx)
+void TypedArrayPrototype::method_get_byteLength(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<TypedArray> v(scope, ctx->thisObject());
+ Scoped<TypedArray> v(scope, callData->thisObject);
if (!v)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
- return Encode(v->d()->byteLength);
+ scope.result = Encode(v->d()->byteLength);
}
-ReturnedValue TypedArrayPrototype::method_get_byteOffset(CallContext *ctx)
+void TypedArrayPrototype::method_get_byteOffset(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<TypedArray> v(scope, ctx->thisObject());
+ Scoped<TypedArray> v(scope, callData->thisObject);
if (!v)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
- return Encode(v->d()->byteOffset);
+ scope.result = Encode(v->d()->byteOffset);
}
-ReturnedValue TypedArrayPrototype::method_get_length(CallContext *ctx)
+void TypedArrayPrototype::method_get_length(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<TypedArray> v(scope, ctx->thisObject());
+ Scoped<TypedArray> v(scope, callData->thisObject);
if (!v)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
- return Encode(v->d()->byteLength/v->d()->type->bytesPerElement);
+ scope.result = Encode(v->d()->byteLength/v->d()->type->bytesPerElement);
}
-ReturnedValue TypedArrayPrototype::method_set(CallContext *ctx)
+void TypedArrayPrototype::method_set(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<TypedArray> a(scope, ctx->thisObject());
+ Scoped<TypedArray> a(scope, callData->thisObject);
if (!a)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
Scoped<ArrayBuffer> buffer(scope, a->d()->buffer);
if (!buffer)
scope.engine->throwTypeError();
- double doffset = ctx->argc() >= 2 ? ctx->args()[1].toInteger() : 0;
+ double doffset = callData->argc >= 2 ? callData->args[1].toInteger() : 0;
if (scope.engine->hasException)
- return Encode::undefined();
+ RETURN_UNDEFINED();
if (doffset < 0 || doffset >= UINT_MAX)
- return scope.engine->throwRangeError(QStringLiteral("TypedArray.set: out of range"));
+ RETURN_RESULT(scope.engine->throwRangeError(QStringLiteral("TypedArray.set: out of range")));
uint offset = (uint)doffset;
uint elementSize = a->d()->type->bytesPerElement;
- Scoped<TypedArray> srcTypedArray(scope, ctx->args()[0]);
+ Scoped<TypedArray> srcTypedArray(scope, callData->args[0]);
if (!srcTypedArray) {
// src is a regular object
- ScopedObject o(scope, ctx->args()[0].toObject(scope.engine));
+ ScopedObject o(scope, callData->args[0].toObject(scope.engine));
if (scope.engine->hasException || !o)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
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();
+ THROW_TYPE_ERROR();
if (offset + l > a->length())
- return scope.engine->throwRangeError(QStringLiteral("TypedArray.set: out of range"));
+ RETURN_RESULT(scope.engine->throwRangeError(QStringLiteral("TypedArray.set: out of range")));
uint idx = 0;
char *b = buffer->d()->data->data() + a->d()->byteOffset + offset*elementSize;
@@ -519,28 +514,28 @@ ReturnedValue TypedArrayPrototype::method_set(CallContext *ctx)
val = o->getIndexed(idx);
a->d()->type->write(scope.engine, b, 0, val);
if (scope.engine->hasException)
- return Encode::undefined();
+ RETURN_UNDEFINED();
++idx;
b += elementSize;
}
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
// src is a typed array
Scoped<ArrayBuffer> srcBuffer(scope, srcTypedArray->d()->buffer);
if (!srcBuffer)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
uint l = srcTypedArray->length();
if (offset + l > a->length())
- return scope.engine->throwRangeError(QStringLiteral("TypedArray.set: out of range"));
+ RETURN_RESULT(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();
+ RETURN_UNDEFINED();
}
char *srcCopy = 0;
@@ -564,28 +559,27 @@ ReturnedValue TypedArrayPrototype::method_set(CallContext *ctx)
if (srcCopy)
delete [] srcCopy;
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
-ReturnedValue TypedArrayPrototype::method_subarray(CallContext *ctx)
+void TypedArrayPrototype::method_subarray(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<TypedArray> a(scope, ctx->thisObject());
+ Scoped<TypedArray> a(scope, callData->thisObject);
if (!a)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
Scoped<ArrayBuffer> buffer(scope, a->d()->buffer);
if (!buffer)
- return scope.engine->throwTypeError();
+ THROW_TYPE_ERROR();
int len = a->length();
- double b = ctx->argc() > 0 ? ctx->args()[0].toInteger() : 0;
+ double b = callData->argc > 0 ? callData->args[0].toInteger() : 0;
if (b < 0)
b = len + b;
uint begin = (uint)qBound(0., b, (double)len);
- double e = ctx->argc() < 2 || ctx->args()[1].isUndefined() ? len : ctx->args()[1].toInteger();
+ double e = callData->argc < 2 || callData->args[1].isUndefined() ? len : callData->args[1].toInteger();
if (e < 0)
e = len + e;
uint end = (uint)qBound(0., e, (double)len);
@@ -593,18 +587,17 @@ ReturnedValue TypedArrayPrototype::method_subarray(CallContext *ctx)
end = begin;
if (scope.engine->hasException)
- return Encode::undefined();
+ RETURN_UNDEFINED();
int newLen = end - begin;
ScopedFunctionObject 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);
- constructor->construct(scope, callData);
- return scope.result.asReturnedValue();
+ THROW_TYPE_ERROR();
+
+ ScopedCallData cData(scope, 3);
+ cData->args[0] = buffer;
+ cData->args[1] = Encode(a->d()->byteOffset + begin*a->d()->type->bytesPerElement);
+ cData->args[2] = Encode(newLen);
+ constructor->construct(scope, cData);
}
diff --git a/src/qml/jsruntime/qv4typedarray_p.h b/src/qml/jsruntime/qv4typedarray_p.h
index 0112d2e4a1..eefed2db4b 100644
--- a/src/qml/jsruntime/qv4typedarray_p.h
+++ b/src/qml/jsruntime/qv4typedarray_p.h
@@ -151,13 +151,13 @@ struct TypedArrayPrototype : 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 void method_get_buffer(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_get_byteLength(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_get_byteOffset(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_get_length(const BuiltinFunction *, Scope &scope, CallData *callData);
- static ReturnedValue method_set(CallContext *ctx);
- static ReturnedValue method_subarray(CallContext *ctx);
+ static void method_set(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_subarray(const BuiltinFunction *, Scope &scope, CallData *callData);
};
inline void
diff --git a/src/qml/jsruntime/qv4variantobject.cpp b/src/qml/jsruntime/qv4variantobject.cpp
index 455a7ccb65..5cab4c5386 100644
--- a/src/qml/jsruntime/qv4variantobject.cpp
+++ b/src/qml/jsruntime/qv4variantobject.cpp
@@ -113,67 +113,68 @@ void VariantPrototype::init()
defineDefaultProperty(engine()->id_toString(), method_toString, 0);
}
-QV4::ReturnedValue VariantPrototype::method_preserve(CallContext *ctx)
+void VariantPrototype::method_preserve(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<VariantObject> o(scope, ctx->thisObject().as<QV4::VariantObject>());
+ Scoped<VariantObject> o(scope, callData->thisObject.as<QV4::VariantObject>());
if (o && o->d()->isScarce())
o->d()->addVmePropertyReference();
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
-QV4::ReturnedValue VariantPrototype::method_destroy(CallContext *ctx)
+void VariantPrototype::method_destroy(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<VariantObject> o(scope, ctx->thisObject().as<QV4::VariantObject>());
+ Scoped<VariantObject> o(scope, callData->thisObject.as<QV4::VariantObject>());
if (o) {
if (o->d()->isScarce())
o->d()->addVmePropertyReference();
o->d()->data() = QVariant();
}
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
-QV4::ReturnedValue VariantPrototype::method_toString(CallContext *ctx)
+void VariantPrototype::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<VariantObject> o(scope, ctx->thisObject().as<QV4::VariantObject>());
+ Scoped<VariantObject> o(scope, callData->thisObject.as<QV4::VariantObject>());
if (!o)
- return Encode::undefined();
+ RETURN_UNDEFINED();
QString result = o->d()->data().toString();
if (result.isEmpty() && !o->d()->data().canConvert(QVariant::String)) {
result = QLatin1String("QVariant(")
+ QLatin1String(o->d()->data().typeName())
+ QLatin1Char(')');
}
- return Encode(ctx->d()->engine->newString(result));
+ scope.result = scope.engine->newString(result);
}
-QV4::ReturnedValue VariantPrototype::method_valueOf(CallContext *ctx)
+void VariantPrototype::method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- Scoped<VariantObject> o(scope, ctx->thisObject().as<QV4::VariantObject>());
+ Scoped<VariantObject> o(scope, callData->thisObject.as<QV4::VariantObject>());
if (o) {
QVariant v = o->d()->data();
switch (v.type()) {
case QVariant::Invalid:
- return Encode::undefined();
+ scope.result = Encode::undefined();
+ return;
case QVariant::String:
- return Encode(ctx->d()->engine->newString(v.toString()));
+ scope.result = scope.engine->newString(v.toString());
+ return;
case QVariant::Int:
- return Encode(v.toInt());
+ scope.result = Encode(v.toInt());
+ return;
case QVariant::Double:
case QVariant::UInt:
- return Encode(v.toDouble());
+ scope.result = Encode(v.toDouble());
+ return;
case QVariant::Bool:
- return Encode(v.toBool());
+ scope.result = Encode(v.toBool());
+ return;
default:
if (QMetaType::typeFlags(v.userType()) & QMetaType::IsEnumeration)
- return Encode(v.toInt());
+ RETURN_RESULT(Encode(v.toInt()));
break;
}
}
- return ctx->thisObject().asReturnedValue();
+ scope.result = callData->thisObject;
}
QT_END_NAMESPACE
diff --git a/src/qml/jsruntime/qv4variantobject_p.h b/src/qml/jsruntime/qv4variantobject_p.h
index 9a04069c12..ef51b6632d 100644
--- a/src/qml/jsruntime/qv4variantobject_p.h
+++ b/src/qml/jsruntime/qv4variantobject_p.h
@@ -107,10 +107,10 @@ struct VariantPrototype : VariantObject
public:
void init();
- static ReturnedValue method_preserve(CallContext *ctx);
- static ReturnedValue method_destroy(CallContext *ctx);
- static ReturnedValue method_toString(CallContext *ctx);
- static ReturnedValue method_valueOf(CallContext *ctx);
+ static void method_preserve(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_destroy(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_valueOf(const BuiltinFunction *, Scope &scope, CallData *callData);
};
}
diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp
index 622359a7d9..b9183313cd 100644
--- a/src/qml/jsruntime/qv4vme_moth.cpp
+++ b/src/qml/jsruntime/qv4vme_moth.cpp
@@ -347,6 +347,10 @@ Param traceParam(const Param &param)
goto catchException; \
VALUE(param) = tmp; \
}
+// qv4scopedvalue_p.h also defines a CHECK_EXCEPTION macro
+#ifdef CHECK_EXCEPTION
+#undef CHECK_EXCEPTION
+#endif
#define CHECK_EXCEPTION \
if (engine->hasException) \
goto catchException
diff --git a/src/qml/memory/memory.pri b/src/qml/memory/memory.pri
index 04b7566ccc..38fadbf23f 100644
--- a/src/qml/memory/memory.pri
+++ b/src/qml/memory/memory.pri
@@ -6,8 +6,8 @@ SOURCES += \
$$PWD/qv4mm.cpp \
HEADERS += \
- $$PWD/qv4mm_p.h
-
+ $$PWD/qv4mm_p.h \
+ $$PWD/qv4mmdefs_p.h
}
HEADERS += \
diff --git a/src/qml/memory/qv4heap_p.h b/src/qml/memory/qv4heap_p.h
index 5a3797f397..8285ef4de7 100644
--- a/src/qml/memory/qv4heap_p.h
+++ b/src/qml/memory/qv4heap_p.h
@@ -52,6 +52,7 @@
#include <QtCore/QString>
#include <private/qv4global_p.h>
+#include <private/qv4mmdefs_p.h>
#include <QSharedPointer>
// To check if Heap::Base::init is called (meaning, all subclasses did their init and called their
@@ -90,43 +91,31 @@ namespace Heap {
struct Q_QML_EXPORT Base {
void *operator new(size_t) = delete;
- quintptr mm_data; // vtable and markbit
+ const VTable *vt;
inline ReturnedValue asReturnedValue() const;
inline void mark(QV4::ExecutionEngine *engine);
- enum {
- MarkBit = 0x1,
- NotInUse = 0x2,
- PointerMask = ~0x3
- };
-
- void setVtable(const VTable *v) {
- Q_ASSERT(!(mm_data & MarkBit));
- mm_data = reinterpret_cast<quintptr>(v);
- }
- VTable *vtable() const {
- return reinterpret_cast<VTable *>(mm_data & PointerMask);
- }
+ void setVtable(const VTable *v) { vt = v; }
+ const VTable *vtable() const { return vt; }
inline bool isMarked() const {
- return mm_data & MarkBit;
+ const HeapItem *h = reinterpret_cast<const HeapItem *>(this);
+ Chunk *c = h->chunk();
+ Q_ASSERT(!Chunk::testBit(c->extendsBitmap, h - c->realBase()));
+ return Chunk::testBit(c->blackBitmap, h - c->realBase());
}
inline void setMarkBit() {
- mm_data |= MarkBit;
- }
- inline void clearMarkBit() {
- mm_data &= ~MarkBit;
+ const HeapItem *h = reinterpret_cast<const HeapItem *>(this);
+ Chunk *c = h->chunk();
+ Q_ASSERT(!Chunk::testBit(c->extendsBitmap, h - c->realBase()));
+ return Chunk::setBit(c->blackBitmap, h - c->realBase());
}
inline bool inUse() const {
- return !(mm_data & NotInUse);
- }
-
- Base *nextFree() {
- return reinterpret_cast<Base *>(mm_data & PointerMask);
- }
- void setNextFree(Base *m) {
- mm_data = (reinterpret_cast<quintptr>(m) | NotInUse);
+ const HeapItem *h = reinterpret_cast<const HeapItem *>(this);
+ Chunk *c = h->chunk();
+ Q_ASSERT(!Chunk::testBit(c->extendsBitmap, h - c->realBase()));
+ return Chunk::testBit(c->objectBitmap, h - c->realBase());
}
void *operator new(size_t, Managed *m) { return m; }
diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp
index 51eb82059a..6330ef6038 100644
--- a/src/qml/memory/qv4mm.cpp
+++ b/src/qml/memory/qv4mm.cpp
@@ -42,8 +42,12 @@
#include "qv4objectproto_p.h"
#include "qv4mm_p.h"
#include "qv4qobjectwrapper_p.h"
+#include <QtCore/qalgorithms.h>
+#include <QtCore/private/qnumeric_p.h>
#include <qqmlengine.h>
+#include "PageReservation.h"
#include "PageAllocation.h"
+#include "PageAllocationAligned.h"
#include "StdLibExtras.h"
#include <QElapsedTimer>
@@ -56,6 +60,14 @@
#include "qv4alloca_p.h"
#include "qv4profiling_p.h"
+#define MM_DEBUG 0
+
+#if MM_DEBUG
+#define DEBUG qDebug() << "MM:"
+#else
+#define DEBUG if (1) ; else qDebug() << "MM:"
+#endif
+
#ifdef V4_USE_VALGRIND
#include <valgrind/valgrind.h>
#include <valgrind/memcheck.h>
@@ -79,310 +91,616 @@ using namespace WTF;
QT_BEGIN_NAMESPACE
-static uint maxShiftValue()
-{
- static uint result = 0;
- if (!result) {
- result = 6;
- if (Q_UNLIKELY(qEnvironmentVariableIsSet(QV4_MM_MAXBLOCK_SHIFT))) {
- bool ok;
- const uint overrideValue = qgetenv(QV4_MM_MAXBLOCK_SHIFT).toUInt(&ok);
- if (ok && overrideValue <= 11 && overrideValue > 0)
- result = overrideValue;
+namespace QV4 {
+
+enum {
+ MinSlotsGCLimit = QV4::Chunk::AvailableSlots*16,
+ GCOverallocation = 200 /* Max overallocation by the GC in % */
+};
+
+struct MemorySegment {
+ enum {
+ NumChunks = 8*sizeof(quint64),
+ SegmentSize = NumChunks*Chunk::ChunkSize,
+ };
+
+ MemorySegment(size_t size)
+ {
+ size += Chunk::ChunkSize; // make sure we can get enough 64k aligment memory
+ if (size < SegmentSize)
+ size = SegmentSize;
+
+ pageReservation = PageReservation::reserve(size, OSAllocator::JSGCHeapPages);
+ base = reinterpret_cast<Chunk *>((reinterpret_cast<quintptr>(pageReservation.base()) + Chunk::ChunkSize - 1) & ~(Chunk::ChunkSize - 1));
+ nChunks = NumChunks;
+ if (base != pageReservation.base())
+ --nChunks;
+ }
+ MemorySegment(MemorySegment &&other) {
+ qSwap(pageReservation, other.pageReservation);
+ qSwap(base, other.base);
+ qSwap(nChunks, other.nChunks);
+ qSwap(allocatedMap, other.allocatedMap);
+ }
+
+ ~MemorySegment() {
+ if (base)
+ pageReservation.deallocate();
+ }
+
+ void setBit(size_t index) {
+ Q_ASSERT(index < nChunks);
+ quint64 bit = static_cast<quint64>(1) << index;
+// qDebug() << " setBit" << hex << index << (index & (Bits - 1)) << bit;
+ allocatedMap |= bit;
+ }
+ void clearBit(size_t index) {
+ Q_ASSERT(index < nChunks);
+ quint64 bit = static_cast<quint64>(1) << index;
+// qDebug() << " setBit" << hex << index << (index & (Bits - 1)) << bit;
+ allocatedMap &= ~bit;
+ }
+ bool testBit(size_t index) const {
+ Q_ASSERT(index < nChunks);
+ quint64 bit = static_cast<quint64>(1) << index;
+ return (allocatedMap & bit);
+ }
+
+ Chunk *allocate(size_t size);
+ void free(Chunk *chunk, size_t size) {
+ DEBUG << "freeing chunk" << chunk;
+ size_t index = static_cast<size_t>(chunk - base);
+ size_t end = index + (size - 1)/Chunk::ChunkSize + 1;
+ while (index < end) {
+ Q_ASSERT(testBit(index));
+ clearBit(index);
+ ++index;
}
+
+ size_t pageSize = WTF::pageSize();
+ size = (size + pageSize - 1) & ~(pageSize - 1);
+ pageReservation.decommit(chunk, size);
+ }
+
+ bool contains(Chunk *c) const {
+ return c >= base && c < base + nChunks;
}
- return result;
-}
-static std::size_t maxChunkSizeValue()
+ PageReservation pageReservation;
+ Chunk *base = 0;
+ quint64 allocatedMap = 0;
+ uint nChunks = 0;
+};
+
+Chunk *MemorySegment::allocate(size_t size)
{
- static std::size_t result = 0;
- if (!result) {
- result = 32 * 1024;
- if (Q_UNLIKELY(qEnvironmentVariableIsSet(QV4_MM_MAX_CHUNK_SIZE))) {
- bool ok;
- const std::size_t overrideValue = qgetenv(QV4_MM_MAX_CHUNK_SIZE).toUInt(&ok);
- if (ok)
- result = overrideValue;
+ size_t requiredChunks = (size + sizeof(Chunk) - 1)/sizeof(Chunk);
+ uint sequence = 0;
+ Chunk *candidate = 0;
+ for (uint i = 0; i < nChunks; ++i) {
+ if (!testBit(i)) {
+ if (!candidate)
+ candidate = base + i;
+ ++sequence;
+ } else {
+ candidate = 0;
+ sequence = 0;
+ }
+ if (sequence == requiredChunks) {
+ pageReservation.commit(candidate, size);
+ for (uint i = 0; i < requiredChunks; ++i)
+ setBit(candidate - base + i);
+ DEBUG << "allocated chunk " << candidate << hex << size;
+ return candidate;
}
}
- return result;
+ return 0;
}
-using namespace QV4;
-
-struct MemoryManager::Data
-{
- const size_t pageSize;
-
- struct ChunkHeader {
- Heap::Base freeItems;
- ChunkHeader *nextNonFull;
- char *itemStart;
- char *itemEnd;
- unsigned itemSize;
- };
+struct ChunkAllocator {
+ ChunkAllocator() {}
- ExecutionEngine *engine;
+ size_t requiredChunkSize(size_t size) {
+ size += Chunk::HeaderSize; // space required for the Chunk header
+ size_t pageSize = WTF::pageSize();
+ size = (size + pageSize - 1) & ~(pageSize - 1); // align to page sizes
+ if (size < Chunk::ChunkSize)
+ size = Chunk::ChunkSize;
+ return size;
+ }
- std::size_t maxChunkSize;
- std::vector<PageAllocation> heapChunks;
- std::size_t unmanagedHeapSize; // the amount of bytes of heap that is not managed by the memory manager, but which is held onto by managed items.
- std::size_t unmanagedHeapSizeGCLimit;
+ Chunk *allocate(size_t size = 0);
+ void free(Chunk *chunk, size_t size = 0);
- struct LargeItem {
- LargeItem *next;
- size_t size;
- void *data;
+ std::vector<MemorySegment> memorySegments;
+};
- Heap::Base *heapObject() {
- return reinterpret_cast<Heap::Base *>(&data);
+Chunk *ChunkAllocator::allocate(size_t size)
+{
+ size = requiredChunkSize(size);
+ for (auto &m : memorySegments) {
+ if (~m.allocatedMap) {
+ Chunk *c = m.allocate(size);
+ if (c)
+ return c;
}
- };
-
- LargeItem *largeItems;
- std::size_t totalLargeItemsAllocated;
+ }
- enum { MaxItemSize = 512 };
- ChunkHeader *nonFullChunks[MaxItemSize/16];
- uint nChunks[MaxItemSize/16];
- uint availableItems[MaxItemSize/16];
- uint allocCount[MaxItemSize/16];
- int totalItems;
- int totalAlloc;
- uint maxShift;
+ // allocate a new segment
+ memorySegments.push_back(MemorySegment(size));
+ Chunk *c = memorySegments.back().allocate(size);
+ Q_ASSERT(c);
+ return c;
+}
- bool gcBlocked;
- bool aggressiveGC;
- bool gcStats;
- bool unused; // suppress padding warning
+void ChunkAllocator::free(Chunk *chunk, size_t size)
+{
+ size = requiredChunkSize(size);
+ for (auto &m : memorySegments) {
+ if (m.contains(chunk)) {
+ m.free(chunk, size);
+ return;
+ }
+ }
+ Q_ASSERT(false);
+}
- // statistics:
-#ifdef DETAILED_MM_STATS
- QVector<unsigned> allocSizeCounters;
-#endif // DETAILED_MM_STATS
- Data()
- : pageSize(WTF::pageSize())
- , engine(0)
- , maxChunkSize(maxChunkSizeValue())
- , unmanagedHeapSize(0)
- , unmanagedHeapSizeGCLimit(MIN_UNMANAGED_HEAPSIZE_GC_LIMIT)
- , largeItems(0)
- , totalLargeItemsAllocated(0)
- , totalItems(0)
- , totalAlloc(0)
- , maxShift(maxShiftValue())
- , gcBlocked(false)
- , aggressiveGC(!qEnvironmentVariableIsEmpty("QV4_MM_AGGRESSIVE_GC"))
- , gcStats(!qEnvironmentVariableIsEmpty(QV4_MM_STATS))
- {
- memset(nonFullChunks, 0, sizeof(nonFullChunks));
- memset(nChunks, 0, sizeof(nChunks));
- memset(availableItems, 0, sizeof(availableItems));
- memset(allocCount, 0, sizeof(allocCount));
+void Chunk::sweep()
+{
+ // DEBUG << "sweeping chunk" << this << (*freeList);
+ HeapItem *o = realBase();
+ for (uint i = 0; i < Chunk::EntriesInBitmap; ++i) {
+ Q_ASSERT((grayBitmap[i] | blackBitmap[i]) == blackBitmap[i]); // check that we don't have gray only objects
+ quintptr toFree = objectBitmap[i] ^ blackBitmap[i];
+ Q_ASSERT((toFree & objectBitmap[i]) == toFree); // check all black objects are marked as being used
+ quintptr e = extendsBitmap[i];
+ // DEBUG << hex << " index=" << i << toFree;
+ while (toFree) {
+ uint index = qCountTrailingZeroBits(toFree);
+ quintptr bit = (static_cast<quintptr>(1) << index);
+
+ toFree ^= bit; // mask out freed slot
+ // DEBUG << " index" << hex << index << toFree;
+
+ // remove all extends slots that have been freed
+ // this is a bit of bit trickery.
+ quintptr mask = (bit << 1) - 1; // create a mask of 1's to the right of and up to the current bit
+ quintptr objmask = e | mask; // or'ing mask with e gives all ones until the end of the current object
+ quintptr result = objmask + 1;
+ Q_ASSERT(qCountTrailingZeroBits(result) - index != 0); // ensure we freed something
+ result |= mask; // ensure we don't clear stuff to the right of the current object
+ e &= result;
+
+ HeapItem *itemToFree = o + index;
+ Heap::Base *b = *itemToFree;
+ if (b->vtable()->destroy) {
+ b->vtable()->destroy(b);
+ b->_checkIsDestroyed();
+ }
+ }
+ objectBitmap[i] = blackBitmap[i];
+ blackBitmap[i] = 0;
+ extendsBitmap[i] = e;
+ o += Chunk::Bits;
}
+ // DEBUG << "swept chunk" << this << "freed" << slotsFreed << "slots.";
+}
- ~Data()
- {
- for (std::vector<PageAllocation>::iterator i = heapChunks.begin(), ei = heapChunks.end(); i != ei; ++i) {
- Q_V4_PROFILE_DEALLOC(engine, i->size(), Profiling::HeapPage);
- i->deallocate();
+void Chunk::freeAll()
+{
+ // DEBUG << "sweeping chunk" << this << (*freeList);
+ HeapItem *o = realBase();
+ for (uint i = 0; i < Chunk::EntriesInBitmap; ++i) {
+ quintptr toFree = objectBitmap[i];
+ quintptr e = extendsBitmap[i];
+ // DEBUG << hex << " index=" << i << toFree;
+ while (toFree) {
+ uint index = qCountTrailingZeroBits(toFree);
+ quintptr bit = (static_cast<quintptr>(1) << index);
+
+ toFree ^= bit; // mask out freed slot
+ // DEBUG << " index" << hex << index << toFree;
+
+ // remove all extends slots that have been freed
+ // this is a bit of bit trickery.
+ quintptr mask = (bit << 1) - 1; // create a mask of 1's to the right of and up to the current bit
+ quintptr objmask = e | mask; // or'ing mask with e gives all ones until the end of the current object
+ quintptr result = objmask + 1;
+ Q_ASSERT(qCountTrailingZeroBits(result) - index != 0); // ensure we freed something
+ result |= mask; // ensure we don't clear stuff to the right of the current object
+ e &= result;
+
+ HeapItem *itemToFree = o + index;
+ Heap::Base *b = *itemToFree;
+ if (b->vtable()->destroy) {
+ b->vtable()->destroy(b);
+ b->_checkIsDestroyed();
+ }
}
+ objectBitmap[i] = 0;
+ blackBitmap[i] = 0;
+ extendsBitmap[i] = e;
+ o += Chunk::Bits;
}
-};
-
-namespace {
+ // DEBUG << "swept chunk" << this << "freed" << slotsFreed << "slots.";
+}
-bool sweepChunk(MemoryManager::Data::ChunkHeader *header, uint *itemsInUse, ExecutionEngine *engine)
+void Chunk::sortIntoBins(HeapItem **bins, uint nBins)
{
- bool isEmpty = true;
- Heap::Base *tail = &header->freeItems;
-// qDebug("chunkStart @ %p, size=%x, pos=%x", header->itemStart, header->itemSize, header->itemSize>>4);
-#ifdef V4_USE_VALGRIND
- VALGRIND_DISABLE_ERROR_REPORTING;
+ HeapItem *base = realBase();
+#if QT_POINTER_SIZE == 8
+ const int start = 0;
+#else
+ const int start = 1;
#endif
- for (char *item = header->itemStart; item <= header->itemEnd; item += header->itemSize) {
- Heap::Base *m = reinterpret_cast<Heap::Base *>(item);
-// qDebug("chunk @ %p, in use: %s, mark bit: %s",
-// item, (m->inUse() ? "yes" : "no"), (m->isMarked() ? "true" : "false"));
-
- Q_ASSERT(qintptr(item) % 16 == 0);
-
- if (m->isMarked()) {
- Q_ASSERT(m->inUse());
- m->clearMarkBit();
- isEmpty = false;
- ++(*itemsInUse);
- } else {
- if (m->inUse()) {
-// qDebug() << "-- collecting it." << m << tail << m->nextFree();
-#ifdef V4_USE_VALGRIND
- VALGRIND_ENABLE_ERROR_REPORTING;
+ for (int i = start; i < EntriesInBitmap; ++i) {
+ quintptr usedSlots = (objectBitmap[i]|extendsBitmap[i]);
+#if QT_POINTER_SIZE == 8
+ if (!i)
+ usedSlots |= (static_cast<quintptr>(1) << (HeaderSize/SlotSize)) - 1;
#endif
- if (m->vtable()->destroy) {
- m->vtable()->destroy(m);
- m->_checkIsDestroyed();
- }
+ uint index = qCountTrailingZeroBits(usedSlots + 1);
+ if (index == Bits)
+ continue;
+ uint freeStart = i*Bits + index;
+ usedSlots &= ~((static_cast<quintptr>(1) << index) - 1);
+ while (i < EntriesInBitmap && !usedSlots) {
+ ++i;
+ usedSlots = (objectBitmap[i]|extendsBitmap[i]);
+ }
+ if (i == EntriesInBitmap)
+ usedSlots = 1;
+ HeapItem *freeItem = base + freeStart;
+
+ uint freeEnd = i*Bits + qCountTrailingZeroBits(usedSlots);
+ uint nSlots = freeEnd - freeStart;
+ Q_ASSERT(freeEnd > freeStart && freeEnd <= NumSlots);
+ freeItem->freeData.availableSlots = nSlots;
+ uint bin = qMin(nBins - 1, nSlots);
+ freeItem->freeData.next = bins[bin];
+ bins[bin] = freeItem;
+ // DEBUG << "binnig item" << freeItem << nSlots << bin << freeItem->freeData.availableSlots;
+ }
+}
- memset(m, 0, sizeof(Heap::Base));
-#ifdef V4_USE_VALGRIND
- VALGRIND_DISABLE_ERROR_REPORTING;
- VALGRIND_MEMPOOL_FREE(engine->memoryManager, m);
+
+template<typename T>
+StackAllocator<T>::StackAllocator(ChunkAllocator *chunkAlloc)
+ : chunkAllocator(chunkAlloc)
+{
+ chunks.push_back(chunkAllocator->allocate());
+ firstInChunk = chunks.back()->first();
+ nextFree = firstInChunk;
+ lastInChunk = firstInChunk + (Chunk::AvailableSlots - 1)/requiredSlots*requiredSlots;
+}
+
+template<typename T>
+void StackAllocator<T>::freeAll()
+{
+ for (auto c : chunks)
+ chunkAllocator->free(c);
+}
+
+template<typename T>
+void StackAllocator<T>::nextChunk() {
+ Q_ASSERT(nextFree == lastInChunk);
+ ++currentChunk;
+ if (currentChunk >= chunks.size()) {
+ Chunk *newChunk = chunkAllocator->allocate();
+ chunks.push_back(newChunk);
+ }
+ firstInChunk = chunks.at(currentChunk)->first();
+ nextFree = firstInChunk;
+ lastInChunk = firstInChunk + (Chunk::AvailableSlots - 1)/requiredSlots*requiredSlots;
+}
+
+template<typename T>
+void QV4::StackAllocator<T>::prevChunk() {
+ Q_ASSERT(nextFree == firstInChunk);
+ Q_ASSERT(chunks.at(currentChunk) == nextFree->chunk());
+ Q_ASSERT(currentChunk > 0);
+ --currentChunk;
+ firstInChunk = chunks.at(currentChunk)->first();
+ lastInChunk = firstInChunk + (Chunk::AvailableSlots - 1)/requiredSlots*requiredSlots;
+ nextFree = lastInChunk;
+}
+
+template struct StackAllocator<Heap::CallContext>;
+
+
+HeapItem *BlockAllocator::allocate(size_t size, bool forceAllocation) {
+ Q_ASSERT((size % Chunk::SlotSize) == 0);
+ size_t slotsRequired = size >> Chunk::SlotSizeShift;
+#if MM_DEBUG
+ ++allocations[bin];
#endif
-#ifdef V4_USE_HEAPTRACK
- heaptrack_report_free(m);
+
+ HeapItem **last;
+
+ HeapItem *m;
+
+ if (slotsRequired < NumBins - 1) {
+ m = freeBins[slotsRequired];
+ if (m) {
+ freeBins[slotsRequired] = m->freeData.next;
+ goto done;
+ }
+ }
+#if 0
+ for (uint b = bin + 1; b < NumBins - 1; ++b) {
+ if ((m = freeBins[b])) {
+ Q_ASSERT(binForSlots(m->freeData.availableSlots) == b);
+ freeBins[b] = m->freeData.next;
+ // DEBUG << "looking for empty bin" << bin << "size" << size << "found" << b;
+ uint remainingSlots = m->freeData.availableSlots - slotsRequired;
+ // DEBUG << "found free slots of size" << m->freeData.availableSlots << m << "remaining" << remainingSlots;
+ if (remainingSlots < 2) {
+ // avoid too much fragmentation and rather mark the memory as used
+ size += remainingSlots*Chunk::SlotSize;
+ goto done;
+ }
+ HeapItem *remainder = m + slotsRequired;
+ remainder->freeData.availableSlots = remainingSlots;
+ uint binForRemainder = binForSlots(remainingSlots);
+ remainder->freeData.next = freeBins[binForRemainder];
+ freeBins[binForRemainder] = remainder;
+ goto done;
+ }
+ }
#endif
- Q_V4_PROFILE_DEALLOC(engine, header->itemSize, Profiling::SmallItem);
- ++(*itemsInUse);
+ if (nFree >= slotsRequired) {
+ // use bump allocation
+ Q_ASSERT(nextFree);
+ m = nextFree;
+ nextFree += slotsRequired;
+ nFree -= slotsRequired;
+ goto done;
+ }
+
+ // DEBUG << "No matching bin found for item" << size << bin;
+ // search last bin for a large enough item
+ last = &freeBins[NumBins - 1];
+ while ((m = *last)) {
+ if (m->freeData.availableSlots >= slotsRequired) {
+ *last = m->freeData.next; // take it out of the list
+
+ size_t remainingSlots = m->freeData.availableSlots - slotsRequired;
+ // DEBUG << "found large free slots of size" << m->freeData.availableSlots << m << "remaining" << remainingSlots;
+ if (remainingSlots < 2) {
+ // avoid too much fragmentation and rather mark the memory as used
+ size += remainingSlots*Chunk::SlotSize;
+ goto done;
}
- // Relink all free blocks to rewrite references to any released chunk.
- tail->setNextFree(m);
- tail = m;
+ HeapItem *remainder = m + slotsRequired;
+ if (remainingSlots >= 2*NumBins) {
+ if (nFree) {
+ size_t bin = binForSlots(nFree);
+ nextFree->freeData.next = freeBins[bin];
+ nextFree->freeData.availableSlots = nFree;
+ freeBins[bin] = nextFree;
+ }
+ nextFree = remainder;
+ nFree = remainingSlots;
+ } else {
+ remainder->freeData.availableSlots = remainingSlots;
+ size_t binForRemainder = binForSlots(remainingSlots);
+ remainder->freeData.next = freeBins[binForRemainder];
+ freeBins[binForRemainder] = remainder;
+ }
+ goto done;
}
+ last = &m->freeData.next;
}
- tail->setNextFree(0);
-#ifdef V4_USE_VALGRIND
- VALGRIND_ENABLE_ERROR_REPORTING;
+
+ if (!m) {
+ if (!forceAllocation)
+ return 0;
+ Chunk *newChunk = chunkAllocator->allocate();
+ chunks.push_back(newChunk);
+ nextFree = newChunk->first();
+ nFree = Chunk::AvailableSlots;
+ m = nextFree;
+ nextFree += slotsRequired;
+ nFree -= slotsRequired;
+ }
+
+done:
+ m->setAllocatedSlots(slotsRequired);
+ // DEBUG << " " << hex << m->chunk() << m->chunk()->objectBitmap[0] << m->chunk()->extendsBitmap[0] << (m - m->chunk()->realBase());
+ return m;
+}
+
+void BlockAllocator::sweep()
+{
+ nextFree = 0;
+ nFree = 0;
+ memset(freeBins, 0, sizeof(freeBins));
+
+// qDebug() << "BlockAlloc: sweep";
+ usedSlotsAfterLastSweep = 0;
+ for (auto c : chunks) {
+ c->sweep();
+ c->sortIntoBins(freeBins, NumBins);
+// qDebug() << "used slots in chunk" << c << ":" << c->nUsedSlots();
+ usedSlotsAfterLastSweep += c->nUsedSlots();
+ }
+}
+
+void BlockAllocator::freeAll()
+{
+ for (auto c : chunks) {
+ c->freeAll();
+ chunkAllocator->free(c);
+ }
+}
+
+#if MM_DEBUG
+void BlockAllocator::stats() {
+ DEBUG << "MM stats:";
+ QString s;
+ for (int i = 0; i < 10; ++i) {
+ uint c = 0;
+ HeapItem *item = freeBins[i];
+ while (item) {
+ ++c;
+ item = item->freeData.next;
+ }
+ s += QString::number(c) + QLatin1String(", ");
+ }
+ HeapItem *item = freeBins[NumBins - 1];
+ uint c = 0;
+ while (item) {
+ ++c;
+ item = item->freeData.next;
+ }
+ s += QLatin1String("..., ") + QString::number(c);
+ DEBUG << "bins:" << s;
+ QString a;
+ for (int i = 0; i < 10; ++i)
+ a += QString::number(allocations[i]) + QLatin1String(", ");
+ a += QLatin1String("..., ") + QString::number(allocations[NumBins - 1]);
+ DEBUG << "allocs:" << a;
+ memset(allocations, 0, sizeof(allocations));
+}
#endif
- return isEmpty;
+
+
+HeapItem *HugeItemAllocator::allocate(size_t size) {
+ Chunk *c = chunkAllocator->allocate(size);
+ chunks.push_back(HugeChunk{c, size});
+ Chunk::setBit(c->objectBitmap, c->first() - c->realBase());
+ return c->first();
+}
+
+static void freeHugeChunk(ChunkAllocator *chunkAllocator, const HugeItemAllocator::HugeChunk &c)
+{
+ HeapItem *itemToFree = c.chunk->first();
+ Heap::Base *b = *itemToFree;
+ if (b->vtable()->destroy) {
+ b->vtable()->destroy(b);
+ b->_checkIsDestroyed();
+ }
+ chunkAllocator->free(c.chunk, c.size);
+}
+
+void HugeItemAllocator::sweep() {
+ auto isBlack = [this] (const HugeChunk &c) {
+ bool b = c.chunk->first()->isBlack();
+ Chunk::clearBit(c.chunk->blackBitmap, c.chunk->first() - c.chunk->realBase());
+ if (!b)
+ freeHugeChunk(chunkAllocator, c);
+ return !b;
+ };
+
+ auto newEnd = std::remove_if(chunks.begin(), chunks.end(), isBlack);
+ chunks.erase(newEnd, chunks.end());
+}
+
+void HugeItemAllocator::freeAll()
+{
+ for (auto &c : chunks) {
+ freeHugeChunk(chunkAllocator, c);
+ }
}
-} // namespace
MemoryManager::MemoryManager(ExecutionEngine *engine)
: engine(engine)
- , m_d(new Data)
+ , chunkAllocator(new ChunkAllocator)
+ , stackAllocator(chunkAllocator)
+ , blockAllocator(chunkAllocator)
+ , hugeItemAllocator(chunkAllocator)
, m_persistentValues(new PersistentValueStorage(engine))
, m_weakValues(new PersistentValueStorage(engine))
+ , unmanagedHeapSizeGCLimit(MIN_UNMANAGED_HEAPSIZE_GC_LIMIT)
+ , aggressiveGC(!qEnvironmentVariableIsEmpty("QV4_MM_AGGRESSIVE_GC"))
+ , gcStats(!qEnvironmentVariableIsEmpty(QV4_MM_STATS))
{
#ifdef V4_USE_VALGRIND
VALGRIND_CREATE_MEMPOOL(this, 0, true);
#endif
- m_d->engine = engine;
}
-Heap::Base *MemoryManager::allocData(std::size_t size, std::size_t unmanagedSize)
+Heap::Base *MemoryManager::allocString(std::size_t unmanagedSize)
{
- if (m_d->aggressiveGC)
+ if (aggressiveGC)
runGC();
-#ifdef DETAILED_MM_STATS
- willAllocate(size);
-#endif // DETAILED_MM_STATS
- Q_ASSERT(size >= 16);
- Q_ASSERT(size % 16 == 0);
-
-// qDebug() << "unmanagedHeapSize:" << m_d->unmanagedHeapSize << "limit:" << m_d->unmanagedHeapSizeGCLimit << "unmanagedSize:" << unmanagedSize;
- m_d->unmanagedHeapSize += unmanagedSize;
+ const size_t stringSize = align(sizeof(Heap::String));
+ unmanagedHeapSize += unmanagedSize;
bool didGCRun = false;
- if (m_d->unmanagedHeapSize > m_d->unmanagedHeapSizeGCLimit) {
+ if (unmanagedHeapSize > unmanagedHeapSizeGCLimit) {
runGC();
- if (3*m_d->unmanagedHeapSizeGCLimit <= 4*m_d->unmanagedHeapSize)
+ if (3*unmanagedHeapSizeGCLimit <= 4*unmanagedHeapSize)
// more than 75% full, raise limit
- m_d->unmanagedHeapSizeGCLimit = std::max(m_d->unmanagedHeapSizeGCLimit, m_d->unmanagedHeapSize) * 2;
- else if (m_d->unmanagedHeapSize * 4 <= m_d->unmanagedHeapSizeGCLimit)
+ unmanagedHeapSizeGCLimit = std::max(unmanagedHeapSizeGCLimit, unmanagedHeapSize) * 2;
+ else if (unmanagedHeapSize * 4 <= unmanagedHeapSizeGCLimit)
// less than 25% full, lower limit
- m_d->unmanagedHeapSizeGCLimit = qMax(MIN_UNMANAGED_HEAPSIZE_GC_LIMIT, m_d->unmanagedHeapSizeGCLimit/2);
+ unmanagedHeapSizeGCLimit = qMax(MIN_UNMANAGED_HEAPSIZE_GC_LIMIT, unmanagedHeapSizeGCLimit/2);
didGCRun = true;
}
- size_t pos = size >> 4;
-
- // doesn't fit into a small bucket
- if (size >= MemoryManager::Data::MaxItemSize) {
- if (!didGCRun && m_d->totalLargeItemsAllocated > 8 * 1024 * 1024)
+ HeapItem *m = blockAllocator.allocate(stringSize);
+ if (!m) {
+ if (!didGCRun && shouldRunGC())
runGC();
-
- // we use malloc for this
- const size_t totalSize = size + sizeof(MemoryManager::Data::LargeItem);
- Q_V4_PROFILE_ALLOC(engine, totalSize, Profiling::LargeItem);
- MemoryManager::Data::LargeItem *item =
- static_cast<MemoryManager::Data::LargeItem *>(malloc(totalSize));
- memset(item, 0, totalSize);
- item->next = m_d->largeItems;
- item->size = size;
- m_d->largeItems = item;
- m_d->totalLargeItemsAllocated += size;
- return item->heapObject();
+ m = blockAllocator.allocate(stringSize, true);
}
- Heap::Base *m = 0;
- Data::ChunkHeader *header = m_d->nonFullChunks[pos];
- if (header) {
- m = header->freeItems.nextFree();
- goto found;
- }
+ memset(m, 0, stringSize);
+ return *m;
+}
- // try to free up space, otherwise allocate
- if (!didGCRun && m_d->allocCount[pos] > (m_d->availableItems[pos] >> 1) && m_d->totalAlloc > (m_d->totalItems >> 1) && !m_d->aggressiveGC) {
+Heap::Base *MemoryManager::allocData(std::size_t size)
+{
+ if (aggressiveGC)
runGC();
- header = m_d->nonFullChunks[pos];
- if (header) {
- m = header->freeItems.nextFree();
- goto found;
- }
- }
+#ifdef DETAILED_MM_STATS
+ willAllocate(size);
+#endif // DETAILED_MM_STATS
- // no free item available, allocate a new chunk
- {
- // allocate larger chunks at a time to avoid excessive GC, but cap at maximum chunk size (2MB by default)
- uint shift = ++m_d->nChunks[pos];
- if (shift > m_d->maxShift)
- shift = m_d->maxShift;
- std::size_t allocSize = m_d->maxChunkSize*(size_t(1) << shift);
- allocSize = roundUpToMultipleOf(m_d->pageSize, allocSize);
- Q_V4_PROFILE_ALLOC(engine, allocSize, Profiling::HeapPage);
- PageAllocation allocation = PageAllocation::allocate(allocSize, OSAllocator::JSGCHeapPages);
- m_d->heapChunks.push_back(allocation);
-
- header = reinterpret_cast<Data::ChunkHeader *>(allocation.base());
- Q_ASSERT(size <= UINT_MAX);
- header->itemSize = unsigned(size);
- header->itemStart = reinterpret_cast<char *>(allocation.base()) + roundUpToMultipleOf(16, sizeof(Data::ChunkHeader));
- header->itemEnd = reinterpret_cast<char *>(allocation.base()) + allocation.size() - header->itemSize;
-
- header->nextNonFull = m_d->nonFullChunks[pos];
- m_d->nonFullChunks[pos] = header;
-
- Heap::Base *last = &header->freeItems;
- for (char *item = header->itemStart; item <= header->itemEnd; item += header->itemSize) {
- Heap::Base *o = reinterpret_cast<Heap::Base *>(item);
- last->setNextFree(o);
- last = o;
+ Q_ASSERT(size >= Chunk::SlotSize);
+ Q_ASSERT(size % Chunk::SlotSize == 0);
- }
- last->setNextFree(0);
- m = header->freeItems.nextFree();
- Q_ASSERT(header->itemEnd >= header->itemStart);
- const size_t increase = quintptr(header->itemEnd - header->itemStart) / header->itemSize;
- m_d->availableItems[pos] += uint(increase);
- m_d->totalItems += int(increase);
-#ifdef V4_USE_VALGRIND
- VALGRIND_MAKE_MEM_NOACCESS(allocation.base(), allocSize);
- VALGRIND_MEMPOOL_ALLOC(this, header, sizeof(Data::ChunkHeader));
-#endif
-#ifdef V4_USE_HEAPTRACK
- heaptrack_report_alloc(header, sizeof(Data::ChunkHeader));
-#endif
+// qDebug() << "unmanagedHeapSize:" << unmanagedHeapSize << "limit:" << unmanagedHeapSizeGCLimit << "unmanagedSize:" << unmanagedSize;
+
+ if (size > Chunk::DataSize)
+ return *hugeItemAllocator.allocate(size);
+
+ HeapItem *m = blockAllocator.allocate(size);
+ if (!m) {
+ if (shouldRunGC())
+ runGC();
+ m = blockAllocator.allocate(size, true);
}
- found:
-#ifdef V4_USE_VALGRIND
- VALGRIND_MEMPOOL_ALLOC(this, m, size);
-#endif
-#ifdef V4_USE_HEAPTRACK
- heaptrack_report_alloc(m, size);
-#endif
- Q_V4_PROFILE_ALLOC(engine, size, Profiling::SmallItem);
+ memset(m, 0, size);
+ return *m;
+}
- ++m_d->allocCount[pos];
- ++m_d->totalAlloc;
- header->freeItems.setNextFree(m->nextFree());
- if (!header->freeItems.nextFree())
- m_d->nonFullChunks[pos] = header->nextNonFull;
- return m;
+Heap::Object *MemoryManager::allocObjectWithMemberData(std::size_t size, uint nMembers)
+{
+ Heap::Object *o = static_cast<Heap::Object *>(allocData(size));
+
+ // ### Could optimize this and allocate both in one go through the block allocator
+ if (nMembers) {
+ std::size_t memberSize = align(sizeof(Heap::MemberData) + (nMembers - 1)*sizeof(Value));
+// qDebug() << "allocating member data for" << o << nMembers << memberSize;
+ Heap::Base *m;
+ if (memberSize > Chunk::DataSize)
+ m = *hugeItemAllocator.allocate(memberSize);
+ else
+ m = *blockAllocator.allocate(memberSize, true);
+ memset(m, 0, memberSize);
+ o->memberData = static_cast<Heap::MemberData *>(m);
+ o->memberData->setVtable(MemberData::staticVTable());
+ o->memberData->size = static_cast<uint>((memberSize - sizeof(Heap::MemberData) + sizeof(Value))/sizeof(Value));
+ o->memberData->init();
+// qDebug() << " got" << o->memberData << o->memberData->size;
+ }
+ return o;
}
static void drainMarkStack(QV4::ExecutionEngine *engine, Value *markBase)
@@ -486,88 +804,34 @@ void MemoryManager::sweep(bool lastSweep)
}
}
- bool *chunkIsEmpty = static_cast<bool *>(alloca(m_d->heapChunks.size() * sizeof(bool)));
- uint itemsInUse[MemoryManager::Data::MaxItemSize/16];
- memset(itemsInUse, 0, sizeof(itemsInUse));
- memset(m_d->nonFullChunks, 0, sizeof(m_d->nonFullChunks));
-
- for (size_t i = 0; i < m_d->heapChunks.size(); ++i) {
- Data::ChunkHeader *header = reinterpret_cast<Data::ChunkHeader *>(m_d->heapChunks[i].base());
- chunkIsEmpty[i] = sweepChunk(header, &itemsInUse[header->itemSize >> 4], engine);
- }
-
- std::vector<PageAllocation>::iterator chunkIter = m_d->heapChunks.begin();
- for (size_t i = 0; i < m_d->heapChunks.size(); ++i) {
- Q_ASSERT(chunkIter != m_d->heapChunks.end());
- Data::ChunkHeader *header = reinterpret_cast<Data::ChunkHeader *>(chunkIter->base());
- const size_t pos = header->itemSize >> 4;
- Q_ASSERT(header->itemEnd >= header->itemStart);
- const size_t decrease = quintptr(header->itemEnd - header->itemStart) / header->itemSize;
-
- // Release that chunk if it could have been spared since the last GC run without any difference.
- if (chunkIsEmpty[i] && m_d->availableItems[pos] - decrease >= itemsInUse[pos]) {
- Q_V4_PROFILE_DEALLOC(engine, chunkIter->size(), Profiling::HeapPage);
-#ifdef V4_USE_VALGRIND
- VALGRIND_MEMPOOL_FREE(this, header);
-#endif
-#ifdef V4_USE_HEAPTRACK
- heaptrack_report_free(header);
-#endif
- --m_d->nChunks[pos];
- m_d->availableItems[pos] -= uint(decrease);
- m_d->totalItems -= int(decrease);
- chunkIter->deallocate();
- chunkIter = m_d->heapChunks.erase(chunkIter);
- continue;
- } else if (header->freeItems.nextFree()) {
- header->nextNonFull = m_d->nonFullChunks[pos];
- m_d->nonFullChunks[pos] = header;
- }
- ++chunkIter;
- }
-
- Data::LargeItem *i = m_d->largeItems;
- Data::LargeItem **last = &m_d->largeItems;
- while (i) {
- Heap::Base *m = i->heapObject();
- Q_ASSERT(m->inUse());
- if (m->isMarked()) {
- m->clearMarkBit();
- last = &i->next;
- i = i->next;
- continue;
- }
- if (m->vtable()->destroy)
- m->vtable()->destroy(m);
-
- *last = i->next;
- Q_V4_PROFILE_DEALLOC(engine, i->size + sizeof(Data::LargeItem), Profiling::LargeItem);
- free(i);
- i = *last;
- }
+ blockAllocator.sweep();
+ hugeItemAllocator.sweep();
+}
- // some execution contexts are allocated on the stack, make sure we clear their markBit as well
- if (!lastSweep) {
- QV4::ExecutionContext *ctx = engine->currentContext;
- while (ctx) {
- ctx->d()->clearMarkBit();
- ctx = engine->parentContext(ctx);
- }
- }
+bool MemoryManager::shouldRunGC() const
+{
+ size_t total = blockAllocator.totalSlots();
+ size_t usedSlots = blockAllocator.usedSlotsAfterLastSweep;
+ if (total > MinSlotsGCLimit && usedSlots * GCOverallocation < total * 100)
+ return true;
+ return false;
}
+
void MemoryManager::runGC()
{
- if (m_d->gcBlocked) {
+ if (gcBlocked) {
// qDebug() << "Not running GC.";
return;
}
- QScopedValueRollback<bool> gcBlocker(m_d->gcBlocked, true);
+ QScopedValueRollback<bool> gcBlocker(gcBlocked, true);
- if (!m_d->gcStats) {
+ if (!gcStats) {
+// uint oldUsed = allocator.usedMem();
mark();
sweep();
+// DEBUG << "RUN GC: allocated:" << allocator.allocatedMem() << "used before" << oldUsed << "used now" << allocator.usedMem();
} else {
const size_t totalMem = getAllocatedMem();
@@ -577,7 +841,6 @@ void MemoryManager::runGC()
qint64 markTime = t.restart();
const size_t usedBefore = getUsedMem();
const size_t largeItemsBefore = getLargeItemsMem();
- size_t chunksBefore = m_d->heapChunks.size();
sweep();
const size_t usedAfter = getUsedMem();
const size_t largeItemsAfter = getLargeItemsMem();
@@ -586,56 +849,30 @@ void MemoryManager::runGC()
qDebug() << "========== GC ==========";
qDebug() << "Marked object in" << markTime << "ms.";
qDebug() << "Sweeped object in" << sweepTime << "ms.";
- qDebug() << "Allocated" << totalMem << "bytes in" << m_d->heapChunks.size() << "chunks.";
+ qDebug() << "Allocated" << totalMem << "bytes";
qDebug() << "Used memory before GC:" << usedBefore;
qDebug() << "Used memory after GC:" << usedAfter;
qDebug() << "Freed up bytes:" << (usedBefore - usedAfter);
- qDebug() << "Released chunks:" << (chunksBefore - m_d->heapChunks.size());
qDebug() << "Large item memory before GC:" << largeItemsBefore;
qDebug() << "Large item memory after GC:" << largeItemsAfter;
qDebug() << "Large item memory freed up:" << (largeItemsBefore - largeItemsAfter);
qDebug() << "======== End GC ========";
}
-
- memset(m_d->allocCount, 0, sizeof(m_d->allocCount));
- m_d->totalAlloc = 0;
- m_d->totalLargeItemsAllocated = 0;
}
size_t MemoryManager::getUsedMem() const
{
- size_t usedMem = 0;
- for (std::vector<PageAllocation>::const_iterator i = m_d->heapChunks.cbegin(), ei = m_d->heapChunks.cend(); i != ei; ++i) {
- Data::ChunkHeader *header = reinterpret_cast<Data::ChunkHeader *>(i->base());
- for (char *item = header->itemStart; item <= header->itemEnd; item += header->itemSize) {
- Heap::Base *m = reinterpret_cast<Heap::Base *>(item);
- Q_ASSERT(qintptr(item) % 16 == 0);
- if (m->inUse())
- usedMem += header->itemSize;
- }
- }
- return usedMem;
+ return blockAllocator.usedMem();
}
size_t MemoryManager::getAllocatedMem() const
{
- size_t total = 0;
- for (size_t i = 0; i < m_d->heapChunks.size(); ++i)
- total += m_d->heapChunks.at(i).size();
- return total;
+ return blockAllocator.allocatedMem() + hugeItemAllocator.usedMem();
}
size_t MemoryManager::getLargeItemsMem() const
{
- size_t total = 0;
- for (const Data::LargeItem *i = m_d->largeItems; i != 0; i = i->next)
- total += i->size;
- return total;
-}
-
-void MemoryManager::changeUnmanagedHeapSizeUsage(qptrdiff delta)
-{
- m_d->unmanagedHeapSize += delta;
+ return hugeItemAllocator.usedMem();
}
MemoryManager::~MemoryManager()
@@ -643,23 +880,26 @@ MemoryManager::~MemoryManager()
delete m_persistentValues;
sweep(/*lastSweep*/true);
+ blockAllocator.freeAll();
+ hugeItemAllocator.freeAll();
+ stackAllocator.freeAll();
delete m_weakValues;
#ifdef V4_USE_VALGRIND
VALGRIND_DESTROY_MEMPOOL(this);
#endif
+ delete chunkAllocator;
}
-
void MemoryManager::dumpStats() const
{
#ifdef DETAILED_MM_STATS
std::cerr << "=================" << std::endl;
std::cerr << "Allocation stats:" << std::endl;
std::cerr << "Requests for each chunk size:" << std::endl;
- for (int i = 0; i < m_d->allocSizeCounters.size(); ++i) {
- if (unsigned count = m_d->allocSizeCounters[i]) {
+ for (int i = 0; i < allocSizeCounters.size(); ++i) {
+ if (unsigned count = allocSizeCounters[i]) {
std::cerr << "\t" << (i << 4) << " bytes chunks: " << count << std::endl;
}
}
@@ -670,7 +910,7 @@ void MemoryManager::dumpStats() const
void MemoryManager::willAllocate(std::size_t size)
{
unsigned alignedSize = (size + 15) >> 4;
- QVector<unsigned> &counters = m_d->allocSizeCounters;
+ QVector<unsigned> &counters = allocSizeCounters;
if ((unsigned) counters.size() < alignedSize + 1)
counters.resize(alignedSize + 1);
counters[alignedSize]++;
@@ -690,4 +930,7 @@ void MemoryManager::collectFromJSStack() const
++v;
}
}
+
+} // namespace QV4
+
QT_END_NAMESPACE
diff --git a/src/qml/memory/qv4mm_p.h b/src/qml/memory/qv4mm_p.h
index e6417cb2e0..00daf8a622 100644
--- a/src/qml/memory/qv4mm_p.h
+++ b/src/qml/memory/qv4mm_p.h
@@ -55,6 +55,7 @@
#include <private/qv4value_p.h>
#include <private/qv4scopedvalue_p.h>
#include <private/qv4object_p.h>
+#include <private/qv4mmdefs_p.h>
#include <QVector>
//#define DETAILED_MM_STATS
@@ -63,35 +64,166 @@
#define QV4_MM_MAX_CHUNK_SIZE "QV4_MM_MAX_CHUNK_SIZE"
#define QV4_MM_STATS "QV4_MM_STATS"
+#define MM_DEBUG 0
+
QT_BEGIN_NAMESPACE
namespace QV4 {
-struct GCDeletable;
+struct ChunkAllocator;
+
+template<typename T>
+struct StackAllocator {
+ Q_STATIC_ASSERT(sizeof(T) < Chunk::DataSize);
+ static const uint requiredSlots = (sizeof(T) + sizeof(HeapItem) - 1)/sizeof(HeapItem);
+
+ StackAllocator(ChunkAllocator *chunkAlloc);
+
+ T *allocate() {
+ T *m = nextFree->as<T>();
+ if (Q_UNLIKELY(nextFree == lastInChunk)) {
+ nextChunk();
+ } else {
+ nextFree += requiredSlots;
+ }
+#if MM_DEBUG
+ Chunk *c = m->chunk();
+ Chunk::setBit(c->objectBitmap, m - c->realBase());
+#endif
+ return m;
+ }
+ void free() {
+#if MM_DEBUG
+ Chunk::clearBit(item->chunk()->objectBitmap, item - item->chunk()->realBase());
+#endif
+ if (Q_UNLIKELY(nextFree == firstInChunk)) {
+ prevChunk();
+ } else {
+ nextFree -= requiredSlots;
+ }
+ }
+
+ void nextChunk();
+ void prevChunk();
+
+ void freeAll();
+
+ ChunkAllocator *chunkAllocator;
+ HeapItem *nextFree = 0;
+ HeapItem *firstInChunk = 0;
+ HeapItem *lastInChunk = 0;
+ std::vector<Chunk *> chunks;
+ uint currentChunk = 0;
+};
+
+struct BlockAllocator {
+ BlockAllocator(ChunkAllocator *chunkAllocator)
+ : chunkAllocator(chunkAllocator)
+ {
+ memset(freeBins, 0, sizeof(freeBins));
+#if MM_DEBUG
+ memset(allocations, 0, sizeof(allocations));
+#endif
+ }
+
+ enum { NumBins = 8 };
+
+ static inline size_t binForSlots(size_t nSlots) {
+ return nSlots >= NumBins ? NumBins - 1 : nSlots;
+ }
+
+#if MM_DEBUG
+ void stats();
+#endif
+
+ HeapItem *allocate(size_t size, bool forceAllocation = false);
+
+ size_t totalSlots() const {
+ return Chunk::AvailableSlots*chunks.size();
+ }
+
+ size_t allocatedMem() const {
+ return chunks.size()*Chunk::DataSize;
+ }
+ size_t usedMem() const {
+ uint used = 0;
+ for (auto c : chunks)
+ used += c->nUsedSlots()*Chunk::SlotSize;
+ return used;
+ }
+
+ void sweep();
+ void freeAll();
+
+ // bump allocations
+ HeapItem *nextFree = 0;
+ size_t nFree = 0;
+ size_t usedSlotsAfterLastSweep = 0;
+ HeapItem *freeBins[NumBins];
+ ChunkAllocator *chunkAllocator;
+ std::vector<Chunk *> chunks;
+#if MM_DEBUG
+ uint allocations[NumBins];
+#endif
+};
+
+struct HugeItemAllocator {
+ HugeItemAllocator(ChunkAllocator *chunkAllocator)
+ : chunkAllocator(chunkAllocator)
+ {}
+
+ HeapItem *allocate(size_t size);
+ void sweep();
+ void freeAll();
+
+ size_t usedMem() const {
+ size_t used = 0;
+ for (const auto &c : chunks)
+ used += c.size;
+ return used;
+ }
+
+ ChunkAllocator *chunkAllocator;
+ struct HugeChunk {
+ Chunk *chunk;
+ size_t size;
+ };
+
+ std::vector<HugeChunk> chunks;
+};
+
class Q_QML_EXPORT MemoryManager
{
Q_DISABLE_COPY(MemoryManager);
public:
- struct Data;
-
-public:
MemoryManager(ExecutionEngine *engine);
~MemoryManager();
// TODO: this is only for 64bit (and x86 with SSE/AVX), so exend it for other architectures to be slightly more efficient (meaning, align on 8-byte boundaries).
// Note: all occurrences of "16" in alloc/dealloc are also due to the alignment.
- static inline std::size_t align(std::size_t size)
- { return (size + 15) & ~0xf; }
+ Q_DECL_CONSTEXPR static inline std::size_t align(std::size_t size)
+ { return (size + Chunk::SlotSize - 1) & ~(Chunk::SlotSize - 1); }
+
+ QV4::Heap::CallContext *allocSimpleCallContext(QV4::ExecutionEngine *v4)
+ {
+ Heap::CallContext *ctxt = stackAllocator.allocate();
+ memset(ctxt, 0, sizeof(Heap::CallContext));
+ ctxt->setVtable(QV4::CallContext::staticVTable());
+ ctxt->init(v4);
+ return ctxt;
+
+ }
+ void freeSimpleCallContext()
+ { stackAllocator.free(); }
template<typename ManagedType>
- inline typename ManagedType::Data *allocManaged(std::size_t size, std::size_t unmanagedSize = 0)
+ inline typename ManagedType::Data *allocManaged(std::size_t size)
{
V4_ASSERT_IS_TRIVIAL(typename ManagedType::Data)
size = align(size);
- Heap::Base *o = allocData(size, unmanagedSize);
- memset(o, 0, size);
+ Heap::Base *o = allocData(size);
o->setVtable(ManagedType::staticVTable());
return static_cast<typename ManagedType::Data *>(o);
}
@@ -99,35 +231,31 @@ public:
template <typename ObjectType>
typename ObjectType::Data *allocateObject(InternalClass *ic)
{
- const int size = (sizeof(typename ObjectType::Data) + (sizeof(Value) - 1)) & ~(sizeof(Value) - 1);
- typename ObjectType::Data *o = allocManaged<ObjectType>(size + ic->size*sizeof(Value));
+ Heap::Object *o = allocObjectWithMemberData(align(sizeof(typename ObjectType::Data)), ic->size);
+ o->setVtable(ObjectType::staticVTable());
o->internalClass = ic;
- o->inlineMemberSize = ic->size;
- o->inlineMemberOffset = size/sizeof(Value);
- return o;
+ return static_cast<typename ObjectType::Data *>(o);
}
template <typename ObjectType>
typename ObjectType::Data *allocateObject()
{
InternalClass *ic = ObjectType::defaultInternalClass(engine);
- const int size = (sizeof(typename ObjectType::Data) + (sizeof(Value) - 1)) & ~(sizeof(Value) - 1);
- typename ObjectType::Data *o = allocManaged<ObjectType>(size + ic->size*sizeof(Value));
+ Heap::Object *o = allocObjectWithMemberData(align(sizeof(typename ObjectType::Data)), ic->size);
+ o->setVtable(ObjectType::staticVTable());
Object *prototype = ObjectType::defaultPrototype(engine);
o->internalClass = ic;
o->prototype = prototype->d();
- o->inlineMemberSize = ic->size;
- o->inlineMemberOffset = size/sizeof(Value);
- return o;
+ return static_cast<typename ObjectType::Data *>(o);
}
template <typename ManagedType, typename Arg1>
typename ManagedType::Data *allocWithStringData(std::size_t unmanagedSize, Arg1 arg1)
{
- Scope scope(engine);
- Scoped<ManagedType> t(scope, allocManaged<ManagedType>(sizeof(typename ManagedType::Data), unmanagedSize));
- t->d_unchecked()->init(this, arg1);
- return t->d();
+ typename ManagedType::Data *o = reinterpret_cast<typename ManagedType::Data *>(allocString(unmanagedSize));
+ o->setVtable(ManagedType::staticVTable());
+ o->init(this, arg1);
+ return o;
}
template <typename ObjectType>
@@ -297,12 +425,15 @@ public:
size_t getAllocatedMem() const;
size_t getLargeItemsMem() const;
- void changeUnmanagedHeapSizeUsage(qptrdiff delta); // called when a JS object grows itself. Specifically: Heap::String::append
+ // called when a JS object grows itself. Specifically: Heap::String::append
+ void changeUnmanagedHeapSizeUsage(qptrdiff delta) { unmanagedHeapSize += delta; }
+
protected:
/// expects size to be aligned
- // TODO: try to inline
- Heap::Base *allocData(std::size_t size, std::size_t unmanagedSize);
+ Heap::Base *allocString(std::size_t unmanagedSize);
+ Heap::Base *allocData(std::size_t size);
+ Heap::Object *allocObjectWithMemberData(std::size_t size, uint nMembers);
#ifdef DETAILED_MM_STATS
void willAllocate(std::size_t size);
@@ -312,13 +443,24 @@ private:
void collectFromJSStack() const;
void mark();
void sweep(bool lastSweep = false);
+ bool shouldRunGC() const;
public:
QV4::ExecutionEngine *engine;
- QScopedPointer<Data> m_d;
+ ChunkAllocator *chunkAllocator;
+ StackAllocator<Heap::CallContext> stackAllocator;
+ BlockAllocator blockAllocator;
+ HugeItemAllocator hugeItemAllocator;
PersistentValueStorage *m_persistentValues;
PersistentValueStorage *m_weakValues;
QVector<Value *> m_pendingFreedObjectWrapperValue;
+
+ std::size_t unmanagedHeapSize = 0; // the amount of bytes of heap that is not managed by the memory manager, but which is held onto by managed items.
+ std::size_t unmanagedHeapSizeGCLimit;
+
+ bool gcBlocked = false;
+ bool aggressiveGC = false;
+ bool gcStats = false;
};
}
diff --git a/src/qml/memory/qv4mmdefs_p.h b/src/qml/memory/qv4mmdefs_p.h
new file mode 100644
index 0000000000..588ae21ee0
--- /dev/null
+++ b/src/qml/memory/qv4mmdefs_p.h
@@ -0,0 +1,262 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QV4MMDEFS_P_H
+#define QV4MMDEFS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <private/qv4global_p.h>
+#include <QtCore/qalgorithms.h>
+#include <qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace QV4 {
+
+/*
+ * Chunks are the basic structure containing GC managed objects.
+ *
+ * Chunks are 64k aligned in memory, so that retrieving the Chunk pointer from a Heap object
+ * is a simple masking operation. Each Chunk has 4 bitmaps for managing purposes,
+ * and 32byte wide slots for the objects following afterwards.
+ *
+ * The gray and black bitmaps are used for mark/sweep.
+ * The object bitmap has a bit set if this location represents the start of a Heap object.
+ * The extends bitmap denotes the extend of an object. It has a cleared bit at the start of the object
+ * and a set bit for all following slots used by the object.
+ *
+ * Free memory has both used and extends bits set to 0.
+ *
+ * This gives the following operations when allocating an object of size s:
+ * Find s/Alignment consecutive free slots in the chunk. Set the object bit for the first
+ * slot to 1. Set the extends bits for all following slots to 1.
+ *
+ * All used slots can be found by object|extents.
+ *
+ * When sweeping, simply copy the black bits over to the object bits.
+ *
+ */
+struct HeapItem;
+struct Chunk {
+ enum {
+ ChunkSize = 64*1024,
+ ChunkShift = 16,
+ SlotSize = 32,
+ SlotSizeShift = 5,
+ NumSlots = ChunkSize/SlotSize,
+ BitmapSize = NumSlots/8,
+ HeaderSize = 4*BitmapSize,
+ DataSize = ChunkSize - HeaderSize,
+ AvailableSlots = DataSize/SlotSize,
+#if QT_POINTER_SIZE == 8
+ Bits = 64,
+ BitShift = 6,
+#else
+ Bits = 32,
+ BitShift = 5,
+#endif
+ EntriesInBitmap = BitmapSize/sizeof(quintptr)
+ };
+ quintptr grayBitmap[BitmapSize/sizeof(quintptr)];
+ quintptr blackBitmap[BitmapSize/sizeof(quintptr)];
+ quintptr objectBitmap[BitmapSize/sizeof(quintptr)];
+ quintptr extendsBitmap[BitmapSize/sizeof(quintptr)];
+ char data[ChunkSize - HeaderSize];
+
+ HeapItem *realBase();
+ HeapItem *first();
+
+ static void setBit(quintptr *bitmap, size_t index) {
+// Q_ASSERT(index >= HeaderSize/SlotSize && index < ChunkSize/SlotSize);
+ bitmap += index >> BitShift;
+ quintptr bit = static_cast<quintptr>(1) << (index & (Bits - 1));
+ *bitmap |= bit;
+ }
+ static void clearBit(quintptr *bitmap, size_t index) {
+// Q_ASSERT(index >= HeaderSize/SlotSize && index < ChunkSize/SlotSize);
+ bitmap += index >> BitShift;
+ quintptr bit = static_cast<quintptr>(1) << (index & (Bits - 1));
+ *bitmap &= ~bit;
+ }
+ static bool testBit(quintptr *bitmap, size_t index) {
+// Q_ASSERT(index >= HeaderSize/SlotSize && index < ChunkSize/SlotSize);
+ bitmap += index >> BitShift;
+ quintptr bit = static_cast<quintptr>(1) << (index & (Bits - 1));
+ return (*bitmap & bit);
+ }
+ static void setBits(quintptr *bitmap, size_t index, size_t nBits) {
+// Q_ASSERT(index >= HeaderSize/SlotSize && index + nBits <= ChunkSize/SlotSize);
+ if (!nBits)
+ return;
+ bitmap += index >> BitShift;
+ index &= (Bits - 1);
+ while (1) {
+ size_t bitsToSet = qMin(nBits, Bits - index);
+ quintptr mask = static_cast<quintptr>(-1) >> (Bits - bitsToSet) << index;
+ *bitmap |= mask;
+ nBits -= bitsToSet;
+ if (!nBits)
+ return;
+ index = 0;
+ ++bitmap;
+ }
+ }
+ static bool hasNonZeroBit(quintptr *bitmap) {
+ for (uint i = 0; i < EntriesInBitmap; ++i)
+ if (bitmap[i])
+ return true;
+ return false;
+ }
+ static uint lowestNonZeroBit(quintptr *bitmap) {
+ for (uint i = 0; i < EntriesInBitmap; ++i) {
+ if (bitmap[i]) {
+ quintptr b = bitmap[i];
+ return i*Bits + qCountTrailingZeroBits(b);
+ }
+ }
+ return 0;
+ }
+
+ uint nFreeSlots() const {
+ return AvailableSlots - nUsedSlots();
+ }
+ uint nUsedSlots() const {
+ uint usedSlots = 0;
+ for (uint i = 0; i < EntriesInBitmap; ++i) {
+ quintptr used = objectBitmap[i] | extendsBitmap[i];
+ usedSlots += qPopulationCount(used);
+ }
+ return usedSlots;
+ }
+
+ void sweep();
+ void freeAll();
+
+ void sortIntoBins(HeapItem **bins, uint nBins);
+};
+
+struct HeapItem {
+ union {
+ struct {
+ HeapItem *next;
+ size_t availableSlots;
+ } freeData;
+ quint64 payload[Chunk::SlotSize/sizeof(quint64)];
+ };
+ operator Heap::Base *() { return reinterpret_cast<Heap::Base *>(this); }
+
+ template<typename T>
+ T *as() { return static_cast<T *>(reinterpret_cast<Heap::Base *>(this)); }
+
+ Chunk *chunk() const {
+ return reinterpret_cast<Chunk *>(reinterpret_cast<quintptr>(this) >> Chunk::ChunkShift << Chunk::ChunkShift);
+ }
+
+ bool isGray() const {
+ Chunk *c = chunk();
+ uint index = this - c->realBase();
+ return Chunk::testBit(c->grayBitmap, index);
+ }
+ bool isBlack() const {
+ Chunk *c = chunk();
+ uint index = this - c->realBase();
+ return Chunk::testBit(c->blackBitmap, index);
+ }
+ bool isInUse() const {
+ Chunk *c = chunk();
+ uint index = this - c->realBase();
+ return Chunk::testBit(c->objectBitmap, index);
+ }
+
+ void setAllocatedSlots(size_t nSlots) {
+// Q_ASSERT(size && !(size % sizeof(HeapItem)));
+ Chunk *c = chunk();
+ size_t index = this - c->realBase();
+// Q_ASSERT(!Chunk::testBit(c->objectBitmap, index));
+ Chunk::setBit(c->objectBitmap, index);
+ Chunk::setBits(c->extendsBitmap, index + 1, nSlots - 1);
+// for (uint i = index + 1; i < nBits - 1; ++i)
+// Q_ASSERT(Chunk::testBit(c->extendsBitmap, i));
+// Q_ASSERT(!Chunk::testBit(c->extendsBitmap, index));
+ }
+
+ // Doesn't report correctly for huge items
+ size_t size() const {
+ Chunk *c = chunk();
+ uint index = this - c->realBase();
+ Q_ASSERT(Chunk::testBit(c->objectBitmap, index));
+ // ### optimize me
+ uint end = index + 1;
+ while (end < Chunk::NumSlots && Chunk::testBit(c->extendsBitmap, end))
+ ++end;
+ return (end - index)*sizeof(HeapItem);
+ }
+};
+
+inline HeapItem *Chunk::realBase()
+{
+ return reinterpret_cast<HeapItem *>(this);
+}
+
+inline HeapItem *Chunk::first()
+{
+ return reinterpret_cast<HeapItem *>(data);
+}
+
+Q_STATIC_ASSERT(sizeof(Chunk) == Chunk::ChunkSize);
+Q_STATIC_ASSERT((1 << Chunk::ChunkShift) == Chunk::ChunkSize);
+Q_STATIC_ASSERT(1 << Chunk::SlotSizeShift == Chunk::SlotSize);
+Q_STATIC_ASSERT(sizeof(HeapItem) == Chunk::SlotSize);
+Q_STATIC_ASSERT(QT_POINTER_SIZE*8 == Chunk::Bits);
+Q_STATIC_ASSERT((1 << Chunk::BitShift) == Chunk::Bits);
+
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index 50ed58e63d..a04f47e6a4 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -1063,11 +1063,11 @@ struct QmlIncubatorObject : public QV4::Object
V4_OBJECT2(QmlIncubatorObject, Object)
V4_NEEDS_DESTROY
- static QV4::ReturnedValue method_get_statusChanged(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_statusChanged(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_status(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_object(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_forceCompletion(QV4::CallContext *ctx);
+ static void method_get_statusChanged(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_set_statusChanged(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_get_status(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_get_object(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_forceCompletion(const BuiltinFunction *, Scope &scope, CallData *callData);
static void markObjects(QV4::Heap::Base *that, QV4::ExecutionEngine *e);
@@ -1415,58 +1415,53 @@ QQmlComponentExtension::QQmlComponentExtension(QV4::ExecutionEngine *v4)
incubationProto.set(v4, proto);
}
-QV4::ReturnedValue QV4::QmlIncubatorObject::method_get_object(QV4::CallContext *ctx)
+void QV4::QmlIncubatorObject::method_get_object(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QmlIncubatorObject> o(scope, ctx->thisObject().as<QmlIncubatorObject>());
+ QV4::Scoped<QmlIncubatorObject> o(scope, callData->thisObject.as<QmlIncubatorObject>());
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- return QV4::QObjectWrapper::wrap(ctx->d()->engine, o->d()->incubator->object());
+ scope.result = QV4::QObjectWrapper::wrap(scope.engine, o->d()->incubator->object());
}
-QV4::ReturnedValue QV4::QmlIncubatorObject::method_forceCompletion(QV4::CallContext *ctx)
+void QV4::QmlIncubatorObject::method_forceCompletion(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QmlIncubatorObject> o(scope, ctx->thisObject().as<QmlIncubatorObject>());
+ QV4::Scoped<QmlIncubatorObject> o(scope, callData->thisObject.as<QmlIncubatorObject>());
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
o->d()->incubator->forceCompletion();
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
-QV4::ReturnedValue QV4::QmlIncubatorObject::method_get_status(QV4::CallContext *ctx)
+void QV4::QmlIncubatorObject::method_get_status(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QmlIncubatorObject> o(scope, ctx->thisObject().as<QmlIncubatorObject>());
+ QV4::Scoped<QmlIncubatorObject> o(scope, callData->thisObject.as<QmlIncubatorObject>());
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- return QV4::Encode(o->d()->incubator->status());
+ scope.result = QV4::Encode(o->d()->incubator->status());
}
-QV4::ReturnedValue QV4::QmlIncubatorObject::method_get_statusChanged(QV4::CallContext *ctx)
+void QV4::QmlIncubatorObject::method_get_statusChanged(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QmlIncubatorObject> o(scope, ctx->thisObject().as<QmlIncubatorObject>());
+ QV4::Scoped<QmlIncubatorObject> o(scope, callData->thisObject.as<QmlIncubatorObject>());
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- return o->d()->statusChanged.asReturnedValue();
+ scope.result = o->d()->statusChanged;
}
-QV4::ReturnedValue QV4::QmlIncubatorObject::method_set_statusChanged(QV4::CallContext *ctx)
+void QV4::QmlIncubatorObject::method_set_statusChanged(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QmlIncubatorObject> o(scope, ctx->thisObject().as<QmlIncubatorObject>());
- if (!o || ctx->argc() < 1)
- return ctx->engine()->throwTypeError();
+ QV4::Scoped<QmlIncubatorObject> o(scope, callData->thisObject.as<QmlIncubatorObject>());
+ if (!o || callData->argc < 1)
+ THROW_TYPE_ERROR();
+ o->d()->statusChanged = callData->args[0];
- o->d()->statusChanged = ctx->args()[0];
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
QQmlComponentExtension::~QQmlComponentExtension()
diff --git a/src/qml/qml/qqmldelayedcallqueue.cpp b/src/qml/qml/qqmldelayedcallqueue.cpp
index 7552e1e82b..d5d2c9a28d 100644
--- a/src/qml/qml/qqmldelayedcallqueue.cpp
+++ b/src/qml/qml/qqmldelayedcallqueue.cpp
@@ -105,17 +105,15 @@ void QQmlDelayedCallQueue::init(QV4::ExecutionEngine* engine)
m_tickedMethod = metaObject.method(methodIndex);
}
-QV4::ReturnedValue QQmlDelayedCallQueue::addUniquelyAndExecuteLater(QV4::CallContext *ctx)
+void QQmlDelayedCallQueue::addUniquelyAndExecuteLater(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- const QV4::CallData *callData = ctx->d()->callData;
-
if (callData->argc == 0)
- V4THROW_ERROR("Qt.callLater: no arguments given");
+ THROW_GENERIC_ERROR("Qt.callLater: no arguments given");
const QV4::FunctionObject *func = callData->args[0].as<QV4::FunctionObject>();
if (!func)
- V4THROW_ERROR("Qt.callLater: first argument not a function or signal");
+ THROW_GENERIC_ERROR("Qt.callLater: first argument not a function or signal");
QPair<QObject *, int> functionData = QV4::QObjectMethod::extractQtMethod(func);
@@ -171,7 +169,7 @@ QV4::ReturnedValue QQmlDelayedCallQueue::addUniquelyAndExecuteLater(QV4::CallCon
m_tickedMethod.invoke(this, Qt::QueuedConnection);
m_callbackOutstanding = true;
}
- return QV4::Encode::undefined();
+ scope.result = QV4::Encode::undefined();
}
void QQmlDelayedCallQueue::storeAnyArguments(DelayedFunctionCall &dfc, const QV4::CallData *callData, int offset, QV4::ExecutionEngine *engine)
diff --git a/src/qml/qml/qqmldelayedcallqueue_p.h b/src/qml/qml/qqmldelayedcallqueue_p.h
index ef899170a2..cffde4f0c0 100644
--- a/src/qml/qml/qqmldelayedcallqueue_p.h
+++ b/src/qml/qml/qqmldelayedcallqueue_p.h
@@ -70,7 +70,7 @@ public:
void init(QV4::ExecutionEngine *);
- QV4::ReturnedValue addUniquelyAndExecuteLater(QV4::CallContext *ctx);
+ void addUniquelyAndExecuteLater(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
public Q_SLOTS:
void ticked();
diff --git a/src/qml/qml/qqmldirparser.cpp b/src/qml/qml/qqmldirparser.cpp
index fde7cc4cef..4cca8a4d58 100644
--- a/src/qml/qml/qqmldirparser.cpp
+++ b/src/qml/qml/qqmldirparser.cpp
@@ -188,6 +188,15 @@ bool QQmlDirParser::parse(const QString &source)
_plugins.append(entry);
+ } else if (sections[0] == QLatin1String("classname")) {
+ if (sectionCount < 2) {
+ reportError(lineNumber, 0,
+ QStringLiteral("classname directive requires an argument, but %1 were provided").arg(sectionCount - 1));
+
+ continue;
+ }
+
+ // Ignore these. qmlimportscanner uses them.
} else if (sections[0] == QLatin1String("internal")) {
if (sectionCount != 3) {
reportError(lineNumber, 0,
diff --git a/src/qml/qml/qqmlincubator.cpp b/src/qml/qml/qqmlincubator.cpp
index 963638ca34..54d0b240f5 100644
--- a/src/qml/qml/qqmlincubator.cpp
+++ b/src/qml/qml/qqmlincubator.cpp
@@ -380,6 +380,23 @@ finishIncubate:
}
}
+void QQmlIncubatorPrivate::cancel(QObject *object, QQmlContext *context)
+{
+ if (!context)
+ context = qmlContext(object);
+ if (!context)
+ return;
+
+ QQmlContextData *data = QQmlContextData::get(context);
+ QQmlIncubatorPrivate *p = (QQmlIncubatorPrivate *)data->activeVMEData;
+ if (!p)
+ return;
+
+ p->vmeGuard.unguard(object);
+ if (!p->creator.isNull())
+ p->creator->cancel(object);
+}
+
/*!
Incubate objects for \a msecs, or until there are no more objects to incubate.
*/
diff --git a/src/qml/qml/qqmlincubator_p.h b/src/qml/qml/qqmlincubator_p.h
index ecf3b6d2ca..758e0a29f6 100644
--- a/src/qml/qml/qqmlincubator_p.h
+++ b/src/qml/qml/qqmlincubator_p.h
@@ -40,6 +40,8 @@
#ifndef QQMLINCUBATOR_P_H
#define QQMLINCUBATOR_P_H
+#include "qqmlincubator.h"
+
#include <private/qintrusivelist_p.h>
#include <private/qqmlvme_p.h>
#include <private/qrecursionwatcher_p.h>
@@ -100,6 +102,9 @@ public:
void forceCompletion(QQmlInstantiationInterrupt &i);
void incubate(QQmlInstantiationInterrupt &i);
+
+ // used by Qt Quick Controls 2
+ Q_QML_PRIVATE_EXPORT static void cancel(QObject *object, QQmlContext *context = 0);
};
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp
index 3876e774c3..712da78807 100644
--- a/src/qml/qml/qqmllocale.cpp
+++ b/src/qml/qml/qqmllocale.cpp
@@ -56,10 +56,17 @@ using namespace QV4;
DEFINE_OBJECT_VTABLE(QQmlLocaleData);
+#define THROW_ERROR(string) \
+ do { \
+ scope.result = scope.engine->throwError(QString::fromUtf8(string)); \
+ return; \
+ } while (false)
+
+
#define GET_LOCALE_DATA_RESOURCE(OBJECT) \
QV4::Scoped<QQmlLocaleData> r(scope, OBJECT.as<QQmlLocaleData>()); \
if (!r) \
- V4THROW_ERROR("Not a valid Locale object")
+ THROW_ERROR("Not a valid Locale object")
static bool isLocaleObject(const QV4::Value &val)
{
@@ -80,215 +87,219 @@ void QQmlDateExtension::registerExtension(QV4::ExecutionEngine *engine)
engine->dateCtor()->defineDefaultProperty(QStringLiteral("timeZoneUpdated"), method_timeZoneUpdated);
}
-QV4::ReturnedValue QQmlDateExtension::method_toLocaleString(QV4::CallContext *ctx)
+void QQmlDateExtension::method_toLocaleString(const BuiltinFunction *b, Scope &scope, CallData *callData)
{
- if (ctx->argc() > 2)
- return QV4::DatePrototype::method_toLocaleString(ctx);
-
- QV4::Scope scope(ctx);
+ if (callData->argc > 2) {
+ QV4::DatePrototype::method_toLocaleString(b, scope, callData);
+ return;
+ }
- QV4::DateObject *date = ctx->thisObject().as<DateObject>();
- if (!date)
- return QV4::DatePrototype::method_toLocaleString(ctx);
+ QV4::DateObject *date = callData->thisObject.as<DateObject>();
+ if (!date) {
+ QV4::DatePrototype::method_toLocaleString(b, scope, callData);
+ return;
+ }
QDateTime dt = date->toQDateTime();
- if (ctx->argc() == 0) {
+ if (callData->argc == 0) {
// Use QLocale for standard toLocaleString() function
QLocale locale;
- return ctx->d()->engine->newString(locale.toString(dt))->asReturnedValue();
+ RETURN_RESULT(scope.engine->newString(locale.toString(dt)));
}
- if (!isLocaleObject(ctx->args()[0]))
- return QV4::DatePrototype::method_toLocaleString(ctx); // Use the default Date toLocaleString()
+ if (!isLocaleObject(callData->args[0])) {
+ QV4::DatePrototype::method_toLocaleString(b, scope, callData); // Use the default Date toLocaleString()
+ return;
+ }
- GET_LOCALE_DATA_RESOURCE(ctx->args()[0]);
+ GET_LOCALE_DATA_RESOURCE(callData->args[0]);
QLocale::FormatType enumFormat = QLocale::LongFormat;
QString formattedDt;
- if (ctx->argc() == 2) {
- if (String *s = ctx->args()[1].stringValue()) {
+ if (callData->argc == 2) {
+ if (String *s = callData->args[1].stringValue()) {
QString format = s->toQString();
formattedDt = r->d()->locale->toString(dt, format);
- } else if (ctx->args()[1].isNumber()) {
- quint32 intFormat = ctx->args()[1].toNumber();
+ } else if (callData->args[1].isNumber()) {
+ quint32 intFormat = callData->args[1].toNumber();
QLocale::FormatType format = QLocale::FormatType(intFormat);
formattedDt = r->d()->locale->toString(dt, format);
} else {
- V4THROW_ERROR("Locale: Date.toLocaleString(): Invalid datetime format");
+ THROW_ERROR("Locale: Date.toLocaleString(): Invalid datetime format");
}
} else {
formattedDt = r->d()->locale->toString(dt, enumFormat);
}
- return ctx->d()->engine->newString(formattedDt)->asReturnedValue();
+ scope.result = scope.engine->newString(formattedDt);
}
-QV4::ReturnedValue QQmlDateExtension::method_toLocaleTimeString(QV4::CallContext *ctx)
+void QQmlDateExtension::method_toLocaleTimeString(const BuiltinFunction *b, Scope &scope, CallData *callData)
{
- if (ctx->argc() > 2)
- return QV4::DatePrototype::method_toLocaleTimeString(ctx);
-
- QV4::Scope scope(ctx);
+ if (callData->argc > 2) {
+ QV4::DatePrototype::method_toLocaleTimeString(b, scope, callData);
+ return;
+ }
- QV4::DateObject *date = ctx->thisObject().as<DateObject>();
- if (!date)
- return QV4::DatePrototype::method_toLocaleTimeString(ctx);
+ QV4::DateObject *date = callData->thisObject.as<DateObject>();
+ if (!date) {
+ QV4::DatePrototype::method_toLocaleTimeString(b, scope, callData);
+ return;
+ }
QDateTime dt = date->toQDateTime();
QTime time = dt.time();
- if (ctx->argc() == 0) {
+ if (callData->argc == 0) {
// Use QLocale for standard toLocaleString() function
QLocale locale;
- return ctx->d()->engine->newString(locale.toString(time))->asReturnedValue();
+ RETURN_RESULT(scope.engine->newString(locale.toString(time)));
}
- if (!isLocaleObject(ctx->args()[0]))
- return QV4::DatePrototype::method_toLocaleTimeString(ctx); // Use the default Date toLocaleTimeString()
+ if (!isLocaleObject(callData->args[0]))
+ return QV4::DatePrototype::method_toLocaleTimeString(b, scope, callData); // Use the default Date toLocaleTimeString()
- GET_LOCALE_DATA_RESOURCE(ctx->args()[0]);
+ GET_LOCALE_DATA_RESOURCE(callData->args[0]);
QLocale::FormatType enumFormat = QLocale::LongFormat;
QString formattedTime;
- if (ctx->argc() == 2) {
- if (String *s = ctx->args()[1].stringValue()) {
+ if (callData->argc == 2) {
+ if (String *s = callData->args[1].stringValue()) {
QString format = s->toQString();
formattedTime = r->d()->locale->toString(time, format);
- } else if (ctx->args()[1].isNumber()) {
- quint32 intFormat = ctx->args()[1].toNumber();
+ } else if (callData->args[1].isNumber()) {
+ quint32 intFormat = callData->args[1].toNumber();
QLocale::FormatType format = QLocale::FormatType(intFormat);
formattedTime = r->d()->locale->toString(time, format);
} else {
- V4THROW_ERROR("Locale: Date.toLocaleTimeString(): Invalid time format");
+ THROW_ERROR("Locale: Date.toLocaleTimeString(): Invalid time format");
}
} else {
formattedTime = r->d()->locale->toString(time, enumFormat);
}
- return ctx->d()->engine->newString(formattedTime)->asReturnedValue();
+ scope.result = scope.engine->newString(formattedTime);
}
-QV4::ReturnedValue QQmlDateExtension::method_toLocaleDateString(QV4::CallContext *ctx)
+void QQmlDateExtension::method_toLocaleDateString(const BuiltinFunction *b, Scope &scope, CallData *callData)
{
- if (ctx->argc() > 2)
- return QV4::DatePrototype::method_toLocaleDateString(ctx);
-
- QV4::Scope scope(ctx);
+ if (callData->argc > 2) {
+ QV4::DatePrototype::method_toLocaleDateString(b, scope, callData);
+ return;
+ }
- QV4::DateObject *dateObj = ctx->thisObject().as<DateObject>();
- if (!dateObj)
- return QV4::DatePrototype::method_toLocaleDateString(ctx);
+ QV4::DateObject *dateObj = callData->thisObject.as<DateObject>();
+ if (!dateObj) {
+ QV4::DatePrototype::method_toLocaleDateString(b, scope, callData);
+ return;
+ }
QDateTime dt = dateObj->toQDateTime();
QDate date = dt.date();
- if (ctx->argc() == 0) {
+ if (callData->argc == 0) {
// Use QLocale for standard toLocaleString() function
QLocale locale;
- return ctx->d()->engine->newString(locale.toString(date))->asReturnedValue();
+ RETURN_RESULT(scope.engine->newString(locale.toString(date)));
}
- if (!isLocaleObject(ctx->args()[0]))
- return QV4::DatePrototype::method_toLocaleDateString(ctx); // Use the default Date toLocaleDateString()
+ if (!isLocaleObject(callData->args[0]))
+ return QV4::DatePrototype::method_toLocaleDateString(b, scope, callData); // Use the default Date toLocaleDateString()
- GET_LOCALE_DATA_RESOURCE(ctx->args()[0]);
+ GET_LOCALE_DATA_RESOURCE(callData->args[0]);
QLocale::FormatType enumFormat = QLocale::LongFormat;
QString formattedDate;
- if (ctx->argc() == 2) {
- if (String *s = ctx->args()[1].stringValue()) {
+ if (callData->argc == 2) {
+ if (String *s = callData->args[1].stringValue()) {
QString format = s->toQString();
formattedDate = r->d()->locale->toString(date, format);
- } else if (ctx->args()[1].isNumber()) {
- quint32 intFormat = ctx->args()[1].toNumber();
+ } else if (callData->args[1].isNumber()) {
+ quint32 intFormat = callData->args[1].toNumber();
QLocale::FormatType format = QLocale::FormatType(intFormat);
formattedDate = r->d()->locale->toString(date, format);
} else {
- V4THROW_ERROR("Locale: Date.loLocaleDateString(): Invalid date format");
+ THROW_ERROR("Locale: Date.loLocaleDateString(): Invalid date format");
}
} else {
formattedDate = r->d()->locale->toString(date, enumFormat);
}
- return ctx->d()->engine->newString(formattedDate)->asReturnedValue();
+ scope.result = scope.engine->newString(formattedDate);
}
-QV4::ReturnedValue QQmlDateExtension::method_fromLocaleString(QV4::CallContext *ctx)
+void QQmlDateExtension::method_fromLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QV4::ExecutionEngine * const engine = ctx->d()->engine;
- if (ctx->argc() == 1) {
- if (String *s = ctx->args()[0].stringValue()) {
+ QV4::ExecutionEngine * const engine = scope.engine;
+ if (callData->argc == 1) {
+ if (String *s = callData->args[0].stringValue()) {
QLocale locale;
QString dateString = s->toQString();
QDateTime dt = locale.toDateTime(dateString);
- return QV4::Encode(engine->newDateObject(dt));
+ RETURN_RESULT(engine->newDateObject(dt));
}
}
- QV4::Scope scope(ctx);
-
- if (ctx->argc() < 1 || ctx->argc() > 3 || !isLocaleObject(ctx->args()[0]))
- V4THROW_ERROR("Locale: Date.fromLocaleString(): Invalid arguments");
+ if (callData->argc < 1 || callData->argc > 3 || !isLocaleObject(callData->args[0]))
+ THROW_ERROR("Locale: Date.fromLocaleString(): Invalid arguments");
- GET_LOCALE_DATA_RESOURCE(ctx->args()[0]);
+ GET_LOCALE_DATA_RESOURCE(callData->args[0]);
QLocale::FormatType enumFormat = QLocale::LongFormat;
QDateTime dt;
- QString dateString = ctx->args()[1].toQStringNoThrow();
- if (ctx->argc() == 3) {
- if (String *s = ctx->args()[2].stringValue()) {
+ QString dateString = callData->args[1].toQStringNoThrow();
+ if (callData->argc == 3) {
+ if (String *s = callData->args[2].stringValue()) {
QString format = s->toQString();
dt = r->d()->locale->toDateTime(dateString, format);
- } else if (ctx->args()[2].isNumber()) {
- quint32 intFormat = ctx->args()[2].toNumber();
+ } else if (callData->args[2].isNumber()) {
+ quint32 intFormat = callData->args[2].toNumber();
QLocale::FormatType format = QLocale::FormatType(intFormat);
dt = r->d()->locale->toDateTime(dateString, format);
} else {
- V4THROW_ERROR("Locale: Date.fromLocaleString(): Invalid datetime format");
+ THROW_ERROR("Locale: Date.fromLocaleString(): Invalid datetime format");
}
} else {
dt = r->d()->locale->toDateTime(dateString, enumFormat);
}
- return QV4::Encode(engine->newDateObject(dt));
+ scope.result = engine->newDateObject(dt);
}
-QV4::ReturnedValue QQmlDateExtension::method_fromLocaleTimeString(QV4::CallContext *ctx)
+void QQmlDateExtension::method_fromLocaleTimeString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QV4::ExecutionEngine * const engine = ctx->d()->engine;
+ QV4::ExecutionEngine * const engine = scope.engine;
- if (ctx->argc() == 1) {
- if (String *s = ctx->args()[0].stringValue()) {
+ if (callData->argc == 1) {
+ if (String *s = callData->args[0].stringValue()) {
QLocale locale;
QString timeString = s->toQString();
QTime time = locale.toTime(timeString);
QDateTime dt = QDateTime::currentDateTime();
dt.setTime(time);
- return QV4::Encode(engine->newDateObject(dt));
+ RETURN_RESULT(engine->newDateObject(dt));
}
}
- if (ctx->argc() < 1 || ctx->argc() > 3 || !isLocaleObject(ctx->args()[0]))
- V4THROW_ERROR("Locale: Date.fromLocaleTimeString(): Invalid arguments");
-
- QV4::Scope scope(ctx);
+ if (callData->argc < 1 || callData->argc > 3 || !isLocaleObject(callData->args[0]))
+ THROW_ERROR("Locale: Date.fromLocaleTimeString(): Invalid arguments");
- GET_LOCALE_DATA_RESOURCE(ctx->args()[0]);
+ GET_LOCALE_DATA_RESOURCE(callData->args[0]);
QLocale::FormatType enumFormat = QLocale::LongFormat;
QTime tm;
- QString dateString = ctx->args()[1].toQStringNoThrow();
- if (ctx->argc() == 3) {
- if (String *s = ctx->args()[2].stringValue()) {
+ QString dateString = callData->args[1].toQStringNoThrow();
+ if (callData->argc == 3) {
+ if (String *s = callData->args[2].stringValue()) {
QString format = s->toQString();
tm = r->d()->locale->toTime(dateString, format);
- } else if (ctx->args()[2].isNumber()) {
- quint32 intFormat = ctx->args()[2].toNumber();
+ } else if (callData->args[2].isNumber()) {
+ quint32 intFormat = callData->args[2].toNumber();
QLocale::FormatType format = QLocale::FormatType(intFormat);
tm = r->d()->locale->toTime(dateString, format);
} else {
- V4THROW_ERROR("Locale: Date.fromLocaleTimeString(): Invalid datetime format");
+ THROW_ERROR("Locale: Date.fromLocaleTimeString(): Invalid datetime format");
}
} else {
tm = r->d()->locale->toTime(dateString, enumFormat);
@@ -300,58 +311,56 @@ QV4::ReturnedValue QQmlDateExtension::method_fromLocaleTimeString(QV4::CallConte
dt.setTime(tm);
}
- return QV4::Encode(engine->newDateObject(dt));
+ RETURN_RESULT(engine->newDateObject(dt));
}
-QV4::ReturnedValue QQmlDateExtension::method_fromLocaleDateString(QV4::CallContext *ctx)
+void QQmlDateExtension::method_fromLocaleDateString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QV4::ExecutionEngine * const engine = ctx->d()->engine;
+ QV4::ExecutionEngine * const engine = scope.engine;
- if (ctx->argc() == 1) {
- if (String *s = ctx->args()[0].stringValue()) {
+ if (callData->argc == 1) {
+ if (String *s = callData->args[0].stringValue()) {
QLocale locale;
QString dateString = s->toQString();
QDate date = locale.toDate(dateString);
- return QV4::Encode(engine->newDateObject(QDateTime(date)));
+ RETURN_RESULT(engine->newDateObject(QDateTime(date)));
}
}
- if (ctx->argc() < 1 || ctx->argc() > 3 || !isLocaleObject(ctx->args()[0]))
- V4THROW_ERROR("Locale: Date.fromLocaleDateString(): Invalid arguments");
+ if (callData->argc < 1 || callData->argc > 3 || !isLocaleObject(callData->args[0]))
+ THROW_ERROR("Locale: Date.fromLocaleDateString(): Invalid arguments");
- QV4::Scope scope(ctx);
-
- GET_LOCALE_DATA_RESOURCE(ctx->args()[0]);
+ GET_LOCALE_DATA_RESOURCE(callData->args[0]);
QLocale::FormatType enumFormat = QLocale::LongFormat;
QDate dt;
- QString dateString = ctx->args()[1].toQStringNoThrow();
- if (ctx->argc() == 3) {
- if (String *s = ctx->args()[2].stringValue()) {
+ QString dateString = callData->args[1].toQStringNoThrow();
+ if (callData->argc == 3) {
+ if (String *s = callData->args[2].stringValue()) {
QString format = s->toQString();
dt = r->d()->locale->toDate(dateString, format);
- } else if (ctx->args()[2].isNumber()) {
- quint32 intFormat = ctx->args()[2].toNumber();
+ } else if (callData->args[2].isNumber()) {
+ quint32 intFormat = callData->args[2].toNumber();
QLocale::FormatType format = QLocale::FormatType(intFormat);
dt = r->d()->locale->toDate(dateString, format);
} else {
- V4THROW_ERROR("Locale: Date.fromLocaleDateString(): Invalid datetime format");
+ THROW_ERROR("Locale: Date.fromLocaleDateString(): Invalid datetime format");
}
} else {
dt = r->d()->locale->toDate(dateString, enumFormat);
}
- return QV4::Encode(engine->newDateObject(QDateTime(dt)));
+ RETURN_RESULT(engine->newDateObject(QDateTime(dt)));
}
-QV4::ReturnedValue QQmlDateExtension::method_timeZoneUpdated(QV4::CallContext *ctx)
+void QQmlDateExtension::method_timeZoneUpdated(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 0)
- V4THROW_ERROR("Locale: Date.timeZoneUpdated(): Invalid arguments");
+ if (callData->argc != 0)
+ THROW_ERROR("Locale: Date.timeZoneUpdated(): Invalid arguments");
QV4::DatePrototype::timezoneUpdated();
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
//-----------------
@@ -364,148 +373,143 @@ void QQmlNumberExtension::registerExtension(QV4::ExecutionEngine *engine)
engine->numberCtor()->defineDefaultProperty(QStringLiteral("fromLocaleString"), method_fromLocaleString);
}
-QV4::ReturnedValue QQmlNumberExtension::method_toLocaleString(QV4::CallContext *ctx)
+void QQmlNumberExtension::method_toLocaleString(const BuiltinFunction *b, Scope &scope, CallData *callData)
{
- if (ctx->argc() > 3)
- V4THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
+ if (callData->argc > 3)
+ THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
- double number = ctx->thisObject().toNumber();
+ double number = callData->thisObject.toNumber();
- if (ctx->argc() == 0) {
+ if (callData->argc == 0) {
// Use QLocale for standard toLocaleString() function
QLocale locale;
- return ctx->d()->engine->newString(locale.toString(number))->asReturnedValue();
+ RETURN_RESULT(scope.engine->newString(locale.toString(number)));
}
- if (!isLocaleObject(ctx->args()[0]))
- return QV4::NumberPrototype::method_toLocaleString(ctx); // Use the default Number toLocaleString()
-
- QV4::Scope scope(ctx);
+ if (!isLocaleObject(callData->args[0])) {
+ QV4::NumberPrototype::method_toLocaleString(b, scope, callData); // Use the default Number toLocaleString()
+ return;
+ }
- GET_LOCALE_DATA_RESOURCE(ctx->args()[0]);
+ GET_LOCALE_DATA_RESOURCE(callData->args[0]);
quint16 format = 'f';
- if (ctx->argc() > 1) {
- if (!ctx->args()[1].isString())
- V4THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
- QString fs = ctx->args()[1].toQString();
+ if (callData->argc > 1) {
+ if (!callData->args[1].isString())
+ THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
+ QString fs = callData->args[1].toQString();
if (fs.length())
format = fs.at(0).unicode();
}
int prec = 2;
- if (ctx->argc() > 2) {
- if (!ctx->args()[2].isNumber())
- V4THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
- prec = ctx->args()[2].toInt32();
+ if (callData->argc > 2) {
+ if (!callData->args[2].isNumber())
+ THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
+ prec = callData->args[2].toInt32();
}
- return ctx->d()->engine->newString(r->d()->locale->toString(number, (char)format, prec))->asReturnedValue();
+ scope.result = scope.engine->newString(r->d()->locale->toString(number, (char)format, prec));
}
-QV4::ReturnedValue QQmlNumberExtension::method_toLocaleCurrencyString(QV4::CallContext *ctx)
+void QQmlNumberExtension::method_toLocaleCurrencyString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() > 2)
- V4THROW_ERROR("Locale: Number.toLocaleCurrencyString(): Invalid arguments");
+ if (callData->argc > 2)
+ THROW_ERROR("Locale: Number.toLocaleCurrencyString(): Invalid arguments");
- double number = ctx->thisObject().toNumber();
+ double number = callData->thisObject.toNumber();
- if (ctx->argc() == 0) {
+ if (callData->argc == 0) {
// Use QLocale for standard toLocaleString() function
QLocale locale;
- return ctx->d()->engine->newString(locale.toString(number))->asReturnedValue();
+ RETURN_RESULT(scope.engine->newString(locale.toString(number)));
}
- if (!isLocaleObject(ctx->args()[0]))
- V4THROW_ERROR("Locale: Number.toLocaleCurrencyString(): Invalid arguments");
-
- QV4::Scope scope(ctx);
+ if (!isLocaleObject(callData->args[0]))
+ THROW_ERROR("Locale: Number.toLocaleCurrencyString(): Invalid arguments");
- GET_LOCALE_DATA_RESOURCE(ctx->args()[0]);
+ GET_LOCALE_DATA_RESOURCE(callData->args[0]);
QString symbol;
- if (ctx->argc() > 1) {
- if (!ctx->args()[1].isString())
- V4THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
- symbol = ctx->args()[1].toQStringNoThrow();
+ if (callData->argc > 1) {
+ if (!callData->args[1].isString())
+ THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments");
+ symbol = callData->args[1].toQStringNoThrow();
}
- return ctx->d()->engine->newString(r->d()->locale->toCurrencyString(number, symbol))->asReturnedValue();
+ RETURN_RESULT(scope.engine->newString(r->d()->locale->toCurrencyString(number, symbol)));
}
-QV4::ReturnedValue QQmlNumberExtension::method_fromLocaleString(QV4::CallContext *ctx)
+void QQmlNumberExtension::method_fromLocaleString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() < 1 || ctx->argc() > 2)
- V4THROW_ERROR("Locale: Number.fromLocaleString(): Invalid arguments");
+ if (callData->argc < 1 || callData->argc > 2)
+ THROW_ERROR("Locale: Number.fromLocaleString(): Invalid arguments");
int numberIdx = 0;
QLocale locale;
- QV4::Scope scope(ctx);
-
- if (ctx->argc() == 2) {
- if (!isLocaleObject(ctx->args()[0]))
- V4THROW_ERROR("Locale: Number.fromLocaleString(): Invalid arguments");
+ if (callData->argc == 2) {
+ if (!isLocaleObject(callData->args[0]))
+ THROW_ERROR("Locale: Number.fromLocaleString(): Invalid arguments");
- GET_LOCALE_DATA_RESOURCE(ctx->args()[0]);
+ GET_LOCALE_DATA_RESOURCE(callData->args[0]);
locale = *r->d()->locale;
numberIdx = 1;
}
- QString ns = ctx->args()[numberIdx].toQString();
+ QString ns = callData->args[numberIdx].toQString();
if (!ns.length())
- return QV4::Encode(Q_QNAN);
+ RETURN_RESULT(QV4::Encode(Q_QNAN));
bool ok = false;
double val = locale.toDouble(ns, &ok);
if (!ok)
- V4THROW_ERROR("Locale: Number.fromLocaleString(): Invalid format")
+ THROW_ERROR("Locale: Number.fromLocaleString(): Invalid format");
- return QV4::Encode(val);
+ scope.result = QV4::Encode(val);
}
//--------------
// Locale object
-QV4::ReturnedValue QQmlLocaleData::method_get_firstDayOfWeek(QV4::CallContext *ctx)
+void QQmlLocaleData::method_get_firstDayOfWeek(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QLocale *locale = getThisLocale(ctx);
+ QLocale *locale = getThisLocale(scope, callData);
if (!locale)
- return QV4::Encode::undefined();
+ return;
int fdow = int(locale->firstDayOfWeek());
if (fdow == 7)
fdow = 0; // Qt::Sunday = 7, but Sunday is 0 in JS Date
- return QV4::Encode(fdow);
+ scope.result = QV4::Encode(fdow);
}
-QV4::ReturnedValue QQmlLocaleData::method_get_measurementSystem(QV4::CallContext *ctx)
+void QQmlLocaleData::method_get_measurementSystem(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QLocale *locale = getThisLocale(ctx);
+ QLocale *locale = getThisLocale(scope, callData);
if (!locale)
- return QV4::Encode::undefined();
- return QV4::Encode(locale->measurementSystem());
+ return;
+ scope.result = QV4::Encode(locale->measurementSystem());
}
-QV4::ReturnedValue QQmlLocaleData::method_get_textDirection(QV4::CallContext *ctx)
+void QQmlLocaleData::method_get_textDirection(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QLocale *locale = getThisLocale(ctx);
+ QLocale *locale = getThisLocale(scope, callData);
if (!locale)
- return QV4::Encode::undefined();
+ return;
- return QV4::Encode(locale->textDirection());
+ scope.result = QV4::Encode(locale->textDirection());
}
-QV4::ReturnedValue QQmlLocaleData::method_get_weekDays(QV4::CallContext *ctx)
+void QQmlLocaleData::method_get_weekDays(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QV4::Scope scope(ctx);
- QLocale *locale = getThisLocale(ctx);
+ QLocale *locale = getThisLocale(scope, callData);
if (!locale)
- return QV4::Encode::undefined();
+ return;
QList<Qt::DayOfWeek> days = locale->weekdays();
- QV4::ScopedArrayObject result(scope, ctx->d()->engine->newArrayObject());
+ QV4::ScopedArrayObject result(scope, scope.engine->newArrayObject());
result->arrayReserve(days.size());
for (int i = 0; i < days.size(); ++i) {
int day = days.at(i);
@@ -515,59 +519,58 @@ QV4::ReturnedValue QQmlLocaleData::method_get_weekDays(QV4::CallContext *ctx)
}
result->setArrayLengthUnchecked(days.size());
- return result.asReturnedValue();
+ scope.result = result.asReturnedValue();
}
-QV4::ReturnedValue QQmlLocaleData::method_get_uiLanguages(QV4::CallContext *ctx)
+void QQmlLocaleData::method_get_uiLanguages(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QV4::Scope scope(ctx);
- QLocale *locale = getThisLocale(ctx);
+ QLocale *locale = getThisLocale(scope, callData);
if (!locale)
- return QV4::Encode::undefined();
+ return;
QStringList langs = locale->uiLanguages();
- QV4::ScopedArrayObject result(scope, ctx->d()->engine->newArrayObject());
+ QV4::ScopedArrayObject result(scope, scope.engine->newArrayObject());
result->arrayReserve(langs.size());
QV4::ScopedValue v(scope);
for (int i = 0; i < langs.size(); ++i)
- result->arrayPut(i, (v = ctx->d()->engine->newString(langs.at(i))));
+ result->arrayPut(i, (v = scope.engine->newString(langs.at(i))));
result->setArrayLengthUnchecked(langs.size());
- return result.asReturnedValue();
+ scope.result = result.asReturnedValue();
}
-QV4::ReturnedValue QQmlLocaleData::method_currencySymbol(QV4::CallContext *ctx)
+void QQmlLocaleData::method_currencySymbol(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QLocale *locale = getThisLocale(ctx);
+ QLocale *locale = getThisLocale(scope, callData);
if (!locale)
- return QV4::Encode::undefined();
+ return;
- if (ctx->argc() > 1)
- V4THROW_ERROR("Locale: currencySymbol(): Invalid arguments");
+ if (callData->argc > 1)
+ THROW_ERROR("Locale: currencySymbol(): Invalid arguments");
QLocale::CurrencySymbolFormat format = QLocale::CurrencySymbol;
- if (ctx->argc() == 1) {
- quint32 intFormat = ctx->args()[0].toNumber();
+ if (callData->argc == 1) {
+ quint32 intFormat = callData->args[0].toNumber();
format = QLocale::CurrencySymbolFormat(intFormat);
}
- return ctx->d()->engine->newString(locale->currencySymbol(format))->asReturnedValue();
+ scope.result = scope.engine->newString(locale->currencySymbol(format));
}
#define LOCALE_FORMAT(FUNC) \
-QV4::ReturnedValue QQmlLocaleData::method_ ##FUNC (QV4::CallContext *ctx) { \
- QLocale *locale = getThisLocale(ctx); \
+void QQmlLocaleData::method_ ##FUNC (const BuiltinFunction *, Scope &scope, CallData *callData) { \
+ QLocale *locale = getThisLocale(scope, callData); \
if (!locale) \
- return QV4::Encode::undefined(); \
- if (ctx->argc() > 1) \
- V4THROW_ERROR("Locale: " #FUNC "(): Invalid arguments"); \
+ return; \
+ if (callData->argc > 1) \
+ THROW_ERROR("Locale: " #FUNC "(): Invalid arguments"); \
QLocale::FormatType format = QLocale::LongFormat;\
- if (ctx->argc() == 1) { \
- quint32 intFormat = ctx->args()[0].toUInt32(); \
+ if (callData->argc == 1) { \
+ quint32 intFormat = callData->args[0].toUInt32(); \
format = QLocale::FormatType(intFormat); \
} \
- return ctx->engine()->newString(locale-> FUNC (format))->asReturnedValue(); \
+ scope.result = scope.engine->newString(locale-> FUNC (format)); \
}
LOCALE_FORMAT(dateTimeFormat)
@@ -576,57 +579,57 @@ LOCALE_FORMAT(dateFormat)
// +1 added to idx because JS is 0-based, whereas QLocale months begin at 1.
#define LOCALE_FORMATTED_MONTHNAME(VARIABLE) \
-QV4::ReturnedValue QQmlLocaleData::method_ ## VARIABLE (QV4::CallContext *ctx) {\
- QLocale *locale = getThisLocale(ctx); \
+void QQmlLocaleData::method_ ## VARIABLE (const BuiltinFunction *, Scope &scope, CallData *callData) {\
+ QLocale *locale = getThisLocale(scope, callData); \
if (!locale) \
- return QV4::Encode::undefined(); \
- if (ctx->argc() < 1 || ctx->argc() > 2) \
- V4THROW_ERROR("Locale: " #VARIABLE "(): Invalid arguments"); \
+ return; \
+ if (callData->argc < 1 || callData->argc > 2) \
+ THROW_ERROR("Locale: " #VARIABLE "(): Invalid arguments"); \
QLocale::FormatType enumFormat = QLocale::LongFormat; \
- int idx = ctx->args()[0].toInt32() + 1; \
+ int idx = callData->args[0].toInt32() + 1; \
if (idx < 1 || idx > 12) \
- V4THROW_ERROR("Locale: Invalid month"); \
+ THROW_ERROR("Locale: Invalid month"); \
QString name; \
- if (ctx->argc() == 2) { \
- if (ctx->args()[1].isNumber()) { \
- quint32 intFormat = ctx->args()[1].toUInt32(); \
+ if (callData->argc == 2) { \
+ if (callData->args[1].isNumber()) { \
+ quint32 intFormat = callData->args[1].toUInt32(); \
QLocale::FormatType format = QLocale::FormatType(intFormat); \
name = locale-> VARIABLE(idx, format); \
} else { \
- V4THROW_ERROR("Locale: Invalid datetime format"); \
+ THROW_ERROR("Locale: Invalid datetime format"); \
} \
} else { \
name = locale-> VARIABLE(idx, enumFormat); \
} \
- return ctx->engine()->newString(name)->asReturnedValue(); \
+ scope.result = scope.engine->newString(name); \
}
// 0 -> 7 as Qt::Sunday is 7, but Sunday is 0 in JS Date
#define LOCALE_FORMATTED_DAYNAME(VARIABLE) \
-QV4::ReturnedValue QQmlLocaleData::method_ ## VARIABLE (QV4::CallContext *ctx) {\
- QLocale *locale = getThisLocale(ctx); \
+void QQmlLocaleData::method_ ## VARIABLE (const BuiltinFunction *, Scope &scope, CallData *callData) {\
+ QLocale *locale = getThisLocale(scope, callData); \
if (!locale) \
- return QV4::Encode::undefined(); \
- if (ctx->argc() < 1 || ctx->argc() > 2) \
- V4THROW_ERROR("Locale: " #VARIABLE "(): Invalid arguments"); \
+ return; \
+ if (callData->argc < 1 || callData->argc > 2) \
+ THROW_ERROR("Locale: " #VARIABLE "(): Invalid arguments"); \
QLocale::FormatType enumFormat = QLocale::LongFormat; \
- int idx = ctx->args()[0].toInt32(); \
+ int idx = callData->args[0].toInt32(); \
if (idx < 0 || idx > 7) \
- V4THROW_ERROR("Locale: Invalid day"); \
+ THROW_ERROR("Locale: Invalid day"); \
if (idx == 0) idx = 7; \
QString name; \
- if (ctx->argc() == 2) { \
- if (ctx->args()[1].isNumber()) { \
- quint32 intFormat = ctx->args()[1].toUInt32(); \
+ if (callData->argc == 2) { \
+ if (callData->args[1].isNumber()) { \
+ quint32 intFormat = callData->args[1].toUInt32(); \
QLocale::FormatType format = QLocale::FormatType(intFormat); \
name = locale-> VARIABLE(idx, format); \
} else { \
- V4THROW_ERROR("Locale: Invalid datetime format"); \
+ THROW_ERROR("Locale: Invalid datetime format"); \
} \
} else { \
name = locale-> VARIABLE(idx, enumFormat); \
} \
- return ctx->engine()->newString(name)->asReturnedValue(); \
+ scope.result = scope.engine->newString(name); \
}
LOCALE_FORMATTED_MONTHNAME(monthName)
@@ -634,12 +637,12 @@ LOCALE_FORMATTED_MONTHNAME(standaloneMonthName)
LOCALE_FORMATTED_DAYNAME(dayName)
LOCALE_FORMATTED_DAYNAME(standaloneDayName)
-#define LOCALE_STRING_PROPERTY(VARIABLE) QV4::ReturnedValue QQmlLocaleData::method_get_ ## VARIABLE (QV4::CallContext* ctx) \
+#define LOCALE_STRING_PROPERTY(VARIABLE) void QQmlLocaleData::method_get_ ## VARIABLE (const BuiltinFunction *, Scope &scope, CallData *callData) \
{ \
- QLocale *locale = getThisLocale(ctx); \
+ QLocale *locale = getThisLocale(scope, callData); \
if (!locale) \
- return QV4::Encode::undefined(); \
- return ctx->engine()->newString(locale-> VARIABLE())->asReturnedValue();\
+ return; \
+ scope.result = scope.engine->newString(locale-> VARIABLE());\
}
LOCALE_STRING_PROPERTY(name)
@@ -830,18 +833,22 @@ void QQmlLocale::registerStringLocaleCompare(QV4::ExecutionEngine *engine)
engine->stringPrototype()->defineDefaultProperty(QStringLiteral("localeCompare"), method_localeCompare);
}
-QV4::ReturnedValue QQmlLocale::method_localeCompare(QV4::CallContext *ctx)
+void QQmlLocale::method_localeCompare(const BuiltinFunction *b, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 1 || (!ctx->args()[0].isString() && !ctx->args()[0].as<StringObject>()))
- return QV4::StringPrototype::method_localeCompare(ctx);
+ if (callData->argc != 1 || (!callData->args[0].isString() && !callData->args[0].as<StringObject>())) {
+ QV4::StringPrototype::method_localeCompare(b, scope, callData);
+ return;
+ }
- if (!ctx->thisObject().isString() && !ctx->thisObject().as<StringObject>())
- return QV4::StringPrototype::method_localeCompare(ctx);
+ if (!callData->thisObject.isString() && !callData->thisObject.as<StringObject>()) {
+ QV4::StringPrototype::method_localeCompare(b, scope, callData);
+ return;
+ }
- QString thisString = ctx->thisObject().toQStringNoThrow();
- QString thatString = ctx->args()[0].toQStringNoThrow();
+ QString thisString = callData->thisObject.toQStringNoThrow();
+ QString thatString = callData->args[0].toQStringNoThrow();
- return QV4::Encode(QString::localeAwareCompare(thisString, thatString));
+ scope.result = QV4::Encode(QString::localeAwareCompare(thisString, thatString));
}
/*!
diff --git a/src/qml/qml/qqmllocale_p.h b/src/qml/qml/qqmllocale_p.h
index 275f58db7d..1a2ffc72b0 100644
--- a/src/qml/qml/qqmllocale_p.h
+++ b/src/qml/qml/qqmllocale_p.h
@@ -67,13 +67,13 @@ public:
static void registerExtension(QV4::ExecutionEngine *engine);
private:
- static QV4::ReturnedValue method_toLocaleString(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_toLocaleTimeString(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_toLocaleDateString(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_fromLocaleString(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_fromLocaleTimeString(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_fromLocaleDateString(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_timeZoneUpdated(QV4::CallContext *ctx);
+ static void method_toLocaleString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_toLocaleTimeString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_toLocaleDateString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_fromLocaleString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_fromLocaleTimeString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_fromLocaleDateString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_timeZoneUpdated(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
};
@@ -83,9 +83,9 @@ public:
static void registerExtension(QV4::ExecutionEngine *engine);
private:
- static QV4::ReturnedValue method_toLocaleString(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_fromLocaleString(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_toLocaleCurrencyString(QV4::CallContext *ctx);
+ static void method_toLocaleString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_fromLocaleString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_toLocaleCurrencyString(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
};
@@ -135,7 +135,7 @@ public:
private:
QQmlLocale();
- static QV4::ReturnedValue method_localeCompare(QV4::CallContext *ctx);
+ static void method_localeCompare(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
};
namespace QV4 {
@@ -158,43 +158,43 @@ struct QQmlLocaleData : public QV4::Object
V4_OBJECT2(QQmlLocaleData, Object)
V4_NEEDS_DESTROY
- static QLocale *getThisLocale(QV4::CallContext *ctx) {
- QV4::Object *o = ctx->thisObject().as<Object>();
+ static QLocale *getThisLocale(QV4::Scope &scope, QV4::CallData *callData) {
+ QV4::Object *o = callData->thisObject.as<Object>();
QQmlLocaleData *thisObject = o ? o->as<QQmlLocaleData>() : 0;
if (!thisObject) {
- ctx->engine()->throwTypeError();
+ scope.engine->throwTypeError();
return 0;
}
return thisObject->d()->locale;
}
- static QV4::ReturnedValue method_currencySymbol(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_dateTimeFormat(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_timeFormat(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_dateFormat(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_monthName(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_standaloneMonthName(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_dayName(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_standaloneDayName(QV4::CallContext *ctx);
-
- static QV4::ReturnedValue method_get_firstDayOfWeek(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_measurementSystem(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_textDirection(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_weekDays(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_uiLanguages(QV4::CallContext *ctx);
-
- static QV4::ReturnedValue method_get_name(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_nativeLanguageName(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_nativeCountryName(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_decimalPoint(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_groupSeparator(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_percent(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_zeroDigit(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_negativeSign(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_positiveSign(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_exponential(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_amText(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_pmText(QV4::CallContext *ctx);
+ static void method_currencySymbol(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_dateTimeFormat(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_timeFormat(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_dateFormat(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_monthName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_standaloneMonthName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_dayName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_standaloneDayName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+
+ static void method_get_firstDayOfWeek(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_measurementSystem(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_textDirection(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_weekDays(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_uiLanguages(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+
+ static void method_get_name(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_nativeLanguageName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_nativeCountryName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_decimalPoint(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_groupSeparator(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_percent(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_zeroDigit(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_negativeSign(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_positiveSign(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_exponential(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_amText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_pmText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
};
}
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp
index 09936f6e7a..38a16b8cde 100644
--- a/src/qml/qml/qqmlobjectcreator.cpp
+++ b/src/qml/qml/qqmlobjectcreator.cpp
@@ -1270,6 +1270,21 @@ QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interru
return sharedState->rootContext;
}
+void QQmlObjectCreator::cancel(QObject *object)
+{
+ int last = sharedState->allCreatedObjects.count() - 1;
+ int i = last;
+ while (i >= 0) {
+ if (sharedState->allCreatedObjects.at(i) == object) {
+ if (i < last)
+ qSwap(sharedState->allCreatedObjects[i], sharedState->allCreatedObjects[last]);
+ sharedState->allCreatedObjects.pop();
+ break;
+ }
+ --i;
+ }
+}
+
void QQmlObjectCreator::clear()
{
if (phase == Done || phase == Finalizing || phase == Startup)
diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h
index caee7b9d1d..982324be3c 100644
--- a/src/qml/qml/qqmlobjectcreator_p.h
+++ b/src/qml/qml/qqmlobjectcreator_p.h
@@ -90,6 +90,7 @@ public:
QObject *create(int subComponentIndex = -1, QObject *parent = 0, QQmlInstantiationInterrupt *interrupt = 0);
bool populateDeferredProperties(QObject *instance);
QQmlContextData *finalize(QQmlInstantiationInterrupt &interrupt);
+ void cancel(QObject *object);
void clear();
QQmlComponentAttached **componentAttachment() const { return &sharedState->componentAttached; }
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index ac993a1037..5b1bba46dd 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -2575,50 +2575,11 @@ void QQmlTypeData::resolveTypes()
int majorVersion = -1;
int minorVersion = -1;
- QQmlImportNamespace *typeNamespace = 0;
- QList<QQmlError> errors;
const QString name = stringAt(unresolvedRef.key());
- bool typeFound = m_importCache.resolveType(name, &ref.type,
- &majorVersion, &minorVersion, &typeNamespace, &errors);
- if (!typeNamespace && !typeFound && !m_implicitImportLoaded) {
- // Lazy loading of implicit import
- if (loadImplicitImport()) {
- // Try again to find the type
- errors.clear();
- typeFound = m_importCache.resolveType(name, &ref.type,
- &majorVersion, &minorVersion, &typeNamespace, &errors);
- } else {
- return; //loadImplicitImport() hit an error, and called setError already
- }
- }
-
- if ((!typeFound || typeNamespace) && reportErrors) {
- // Known to not be a type:
- // - known to be a namespace (Namespace {})
- // - type with unknown namespace (UnknownNamespace.SomeType {})
- QQmlError error;
- if (typeNamespace) {
- error.setDescription(QQmlTypeLoader::tr("Namespace %1 cannot be used as a type").arg(name));
- } else {
- if (errors.size()) {
- error = errors.takeFirst();
- } else {
- // this should not be possible!
- // Description should come from error provided by addImport() function.
- error.setDescription(QQmlTypeLoader::tr("Unreported error adding script import to import database"));
- }
- error.setUrl(m_importCache.baseUrl());
- error.setDescription(QQmlTypeLoader::tr("%1 %2").arg(name).arg(error.description()));
- }
- error.setLine(unresolvedRef->location.line);
- error.setColumn(unresolvedRef->location.column);
-
- errors.prepend(error);
- setError(errors);
+ if (!resolveType(name, majorVersion, minorVersion, ref, unresolvedRef->location.line, unresolvedRef->location.column, reportErrors) && reportErrors)
return;
- }
if (ref.type && ref.type->isComposite()) {
ref.typeData = typeLoader()->getType(ref.type->sourceUrl());
@@ -2687,7 +2648,7 @@ QQmlCompileError QQmlTypeData::buildTypeResolutionCaches(
return noError;
}
-bool QQmlTypeData::resolveType(const QString &typeName, int &majorVersion, int &minorVersion, TypeReference &ref)
+bool QQmlTypeData::resolveType(const QString &typeName, int &majorVersion, int &minorVersion, TypeReference &ref, int lineNumber, int columnNumber, bool reportErrors)
{
QQmlImportNamespace *typeNamespace = 0;
QList<QQmlError> errors;
@@ -2706,7 +2667,7 @@ bool QQmlTypeData::resolveType(const QString &typeName, int &majorVersion, int &
}
}
- if (!typeFound || typeNamespace) {
+ if ((!typeFound || typeNamespace) && reportErrors) {
// Known to not be a type:
// - known to be a namespace (Namespace {})
// - type with unknown namespace (UnknownNamespace.SomeType {})
@@ -2725,6 +2686,11 @@ bool QQmlTypeData::resolveType(const QString &typeName, int &majorVersion, int &
error.setDescription(QQmlTypeLoader::tr("%1 %2").arg(typeName).arg(error.description()));
}
+ if (lineNumber != -1)
+ error.setLine(lineNumber);
+ if (columnNumber != -1)
+ error.setColumn(columnNumber);
+
errors.prepend(error);
setError(errors);
return false;
diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h
index b1d6451974..c60435a2d6 100644
--- a/src/qml/qml/qqmltypeloader_p.h
+++ b/src/qml/qml/qqmltypeloader_p.h
@@ -456,7 +456,7 @@ private:
const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache);
void createTypeAndPropertyCaches(const QQmlRefPointer<QQmlTypeNameCache> &importCache,
const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache);
- bool resolveType(const QString &typeName, int &majorVersion, int &minorVersion, TypeReference &ref);
+ bool resolveType(const QString &typeName, int &majorVersion, int &minorVersion, TypeReference &ref, int lineNumber = -1, int columnNumber = -1, bool reportErrors = true);
void scriptImported(QQmlScriptBlob *blob, const QV4::CompiledData::Location &location, const QString &qualifier, const QString &nameSpace) override;
diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp
index 6ce52bb9e5..44b612e7d2 100644
--- a/src/qml/qml/qqmlvaluetypewrapper.cpp
+++ b/src/qml/qml/qqmlvaluetypewrapper.cpp
@@ -312,18 +312,18 @@ bool QQmlValueTypeWrapper::write(QObject *target, int propertyIndex) const
return true;
}
-ReturnedValue QQmlValueTypeWrapper::method_toString(CallContext *ctx)
+void QQmlValueTypeWrapper::method_toString(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Object *o = ctx->thisObject().as<Object>();
+ Object *o = callData->thisObject.as<Object>();
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
QQmlValueTypeWrapper *w = o->as<QQmlValueTypeWrapper>();
if (!w)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
if (QQmlValueTypeReference *ref = w->as<QQmlValueTypeReference>())
if (!ref->readReferenceValue())
- return Encode::undefined();
+ RETURN_UNDEFINED();
QString result;
// Prepare a buffer to pass to QMetaType::convert()
@@ -346,7 +346,7 @@ ReturnedValue QQmlValueTypeWrapper::method_toString(CallContext *ctx)
}
result += QLatin1Char(')');
}
- return Encode(ctx->engine()->newString(result));
+ scope.result = scope.engine->newString(result);
}
ReturnedValue QQmlValueTypeWrapper::get(const Managed *m, String *name, bool *hasProperty)
diff --git a/src/qml/qml/qqmlvaluetypewrapper_p.h b/src/qml/qml/qqmlvaluetypewrapper_p.h
index fec54df770..87f9116056 100644
--- a/src/qml/qml/qqmlvaluetypewrapper_p.h
+++ b/src/qml/qml/qqmlvaluetypewrapper_p.h
@@ -111,7 +111,7 @@ public:
static PropertyAttributes query(const Managed *, String *name);
static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes);
- static QV4::ReturnedValue method_toString(CallContext *ctx);
+ static void method_toString(const BuiltinFunction *, Scope &scope, CallData *callData);
static void initProto(ExecutionEngine *v4);
};
diff --git a/src/qml/qml/qqmlvme.cpp b/src/qml/qml/qqmlvme.cpp
index 72d4ab7e8f..c60f4edc80 100644
--- a/src/qml/qml/qqmlvme.cpp
+++ b/src/qml/qml/qqmlvme.cpp
@@ -120,6 +120,18 @@ void QQmlVMEGuard::guard(QQmlObjectCreator *creator)
m_contexts[0] = creator->parentContextData();
}
+void QQmlVMEGuard::unguard(QObject *object)
+{
+ for (int ii = 0; ii < m_objectCount; ++ii) {
+ if (m_objects[ii] == object) {
+ if (ii < m_objectCount - 1)
+ ::memmove((void *) m_objects[ii], (void *) m_objects[ii + 1], sizeof(QPointer<QObject> *));
+ delete m_objects[--m_objectCount];
+ break;
+ }
+ }
+}
+
void QQmlVMEGuard::clear()
{
delete [] m_objects;
diff --git a/src/qml/qml/qqmlvme_p.h b/src/qml/qml/qqmlvme_p.h
index 99d63380ad..9585b5b6df 100644
--- a/src/qml/qml/qqmlvme_p.h
+++ b/src/qml/qml/qqmlvme_p.h
@@ -131,6 +131,7 @@ public:
~QQmlVMEGuard();
void guard(QQmlObjectCreator *);
+ void unguard(QObject *);
void clear();
bool isOK() const;
diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp
index 22c3c49c58..d0d9f080da 100644
--- a/src/qml/qml/qqmlxmlhttprequest.cpp
+++ b/src/qml/qml/qqmlxmlhttprequest.cpp
@@ -71,10 +71,12 @@ using namespace QV4;
#if QT_CONFIG(xmlstreamreader) && QT_CONFIG(qml_network)
-#define V4THROW_REFERENCE(string) { \
- ScopedObject error(scope, ctx->engine()->newReferenceErrorObject(QStringLiteral(string))); \
- return ctx->engine()->throwError(error); \
- }
+#define V4THROW_REFERENCE(string) \
+ do { \
+ ScopedObject error(scope, scope.engine->newReferenceErrorObject(QStringLiteral(string))); \
+ scope.result = scope.engine->throwError(error); \
+ return; \
+ } while (false)
QT_BEGIN_NAMESPACE
@@ -274,25 +276,25 @@ public:
static void initClass(ExecutionEngine *engine);
// JS API
- static ReturnedValue method_get_nodeName(CallContext *ctx);
- static ReturnedValue method_get_nodeValue(CallContext *ctx);
- static ReturnedValue method_get_nodeType(CallContext *ctx);
- static ReturnedValue method_get_namespaceUri(CallContext *ctx);
-
- static ReturnedValue method_get_parentNode(CallContext *ctx);
- static ReturnedValue method_get_childNodes(CallContext *ctx);
- static ReturnedValue method_get_firstChild(CallContext *ctx);
- static ReturnedValue method_get_lastChild(CallContext *ctx);
- static ReturnedValue method_get_previousSibling(CallContext *ctx);
- static ReturnedValue method_get_nextSibling(CallContext *ctx);
- static ReturnedValue method_get_attributes(CallContext *ctx);
-
- //static ReturnedValue ownerDocument(CallContext *ctx);
- //static ReturnedValue namespaceURI(CallContext *ctx);
- //static ReturnedValue prefix(CallContext *ctx);
- //static ReturnedValue localName(CallContext *ctx);
- //static ReturnedValue baseURI(CallContext *ctx);
- //static ReturnedValue textContent(CallContext *ctx);
+ static void method_get_nodeName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_nodeValue(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_nodeType(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_namespaceUri(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+
+ static void method_get_parentNode(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_childNodes(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_firstChild(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_lastChild(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_previousSibling(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_nextSibling(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_attributes(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+
+ //static void ownerDocument(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ //static void namespaceURI(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ //static void prefix(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ //static void localName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ //static void baseURI(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ //static void textContent(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
static ReturnedValue getProto(ExecutionEngine *v4);
@@ -353,12 +355,12 @@ class Attr : public Node
{
public:
// JS API
- static ReturnedValue method_name(CallContext *ctx);
-// static ReturnedValue specified(CallContext *);
- static ReturnedValue method_value(CallContext *ctx);
- static ReturnedValue method_ownerElement(CallContext *ctx);
-// static ReturnedValue schemaTypeInfo(CallContext *);
-// static ReturnedValue isId(CallContext *c);
+ static void method_name(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+// static void specified(CallContext *);
+ static void method_value(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_ownerElement(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+// static void schemaTypeInfo(CallContext *);
+// static void isId(CallContext *c);
// C++ API
static ReturnedValue prototype(ExecutionEngine *);
@@ -368,7 +370,7 @@ class CharacterData : public Node
{
public:
// JS API
- static ReturnedValue method_length(CallContext *ctx);
+ static void method_length(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
// C++ API
static ReturnedValue prototype(ExecutionEngine *v4);
@@ -378,8 +380,8 @@ class Text : public CharacterData
{
public:
// JS API
- static ReturnedValue method_isElementContentWhitespace(CallContext *ctx);
- static ReturnedValue method_wholeText(CallContext *ctx);
+ static void method_isElementContentWhitespace(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_wholeText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
// C++ API
static ReturnedValue prototype(ExecutionEngine *);
@@ -396,10 +398,10 @@ class Document : public Node
{
public:
// JS API
- static ReturnedValue method_xmlVersion(CallContext *ctx);
- static ReturnedValue method_xmlEncoding(CallContext *ctx);
- static ReturnedValue method_xmlStandalone(CallContext *ctx);
- static ReturnedValue method_documentElement(CallContext *ctx);
+ static void method_xmlVersion(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_xmlEncoding(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_xmlStandalone(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_documentElement(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
// C++ API
static ReturnedValue prototype(ExecutionEngine *);
@@ -418,12 +420,11 @@ void NodeImpl::release()
document->release();
}
-ReturnedValue NodePrototype::method_get_nodeName(CallContext *ctx)
+void NodePrototype::method_get_nodeName(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
QString name;
switch (r->d()->d->type) {
@@ -440,15 +441,14 @@ ReturnedValue NodePrototype::method_get_nodeName(CallContext *ctx)
name = r->d()->d->name;
break;
}
- return Encode(ctx->d()->engine->newString(name));
+ scope.result = Encode(scope.engine->newString(name));
}
-ReturnedValue NodePrototype::method_get_nodeValue(CallContext *ctx)
+void NodePrototype::method_get_nodeValue(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
if (r->d()->d->type == NodeImpl::Document ||
r->d()->d->type == NodeImpl::DocumentFragment ||
@@ -457,135 +457,128 @@ ReturnedValue NodePrototype::method_get_nodeValue(CallContext *ctx)
r->d()->d->type == NodeImpl::Entity ||
r->d()->d->type == NodeImpl::EntityReference ||
r->d()->d->type == NodeImpl::Notation)
- return Encode::null();
+ RETURN_RESULT(Encode::null());
- return Encode(ctx->d()->engine->newString(r->d()->d->data));
+ scope.result = Encode(scope.engine->newString(r->d()->d->data));
}
-ReturnedValue NodePrototype::method_get_nodeType(CallContext *ctx)
+void NodePrototype::method_get_nodeType(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- return Encode(r->d()->d->type);
+ scope.result = Encode(r->d()->d->type);
}
-ReturnedValue NodePrototype::method_get_namespaceUri(CallContext *ctx)
+void NodePrototype::method_get_namespaceUri(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- return Encode(ctx->d()->engine->newString(r->d()->d->namespaceUri));
+ scope.result = Encode(scope.engine->newString(r->d()->d->namespaceUri));
}
-ReturnedValue NodePrototype::method_get_parentNode(CallContext *ctx)
+void NodePrototype::method_get_parentNode(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
if (r->d()->d->parent)
- return Node::create(scope.engine, r->d()->d->parent);
+ scope.result = Node::create(scope.engine, r->d()->d->parent);
else
- return Encode::null();
+ scope.result = Encode::null();
}
-ReturnedValue NodePrototype::method_get_childNodes(CallContext *ctx)
+void NodePrototype::method_get_childNodes(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
- return NodeList::create(scope.engine, r->d()->d);
+ scope.result = NodeList::create(scope.engine, r->d()->d);
}
-ReturnedValue NodePrototype::method_get_firstChild(CallContext *ctx)
+void NodePrototype::method_get_firstChild(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
if (r->d()->d->children.isEmpty())
- return Encode::null();
+ scope.result = Encode::null();
else
- return Node::create(scope.engine, r->d()->d->children.constFirst());
+ scope.result = Node::create(scope.engine, r->d()->d->children.constFirst());
}
-ReturnedValue NodePrototype::method_get_lastChild(CallContext *ctx)
+void NodePrototype::method_get_lastChild(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
if (r->d()->d->children.isEmpty())
- return Encode::null();
+ scope.result = Encode::null();
else
- return Node::create(scope.engine, r->d()->d->children.constLast());
+ scope.result = Node::create(scope.engine, r->d()->d->children.constLast());
}
-ReturnedValue NodePrototype::method_get_previousSibling(CallContext *ctx)
+void NodePrototype::method_get_previousSibling(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
if (!r->d()->d->parent)
- return Encode::null();
+ RETURN_RESULT(Encode::null());
for (int ii = 0; ii < r->d()->d->parent->children.count(); ++ii) {
if (r->d()->d->parent->children.at(ii) == r->d()->d) {
if (ii == 0)
- return Encode::null();
+ scope.result = Encode::null();
else
- return Node::create(scope.engine, r->d()->d->parent->children.at(ii - 1));
+ scope.result = Node::create(scope.engine, r->d()->d->parent->children.at(ii - 1));
+ return;
}
}
- return Encode::null();
+ scope.result = Encode::null();
}
-ReturnedValue NodePrototype::method_get_nextSibling(CallContext *ctx)
+void NodePrototype::method_get_nextSibling(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
if (!r->d()->d->parent)
- return Encode::null();
+ RETURN_RESULT(Encode::null());
for (int ii = 0; ii < r->d()->d->parent->children.count(); ++ii) {
if (r->d()->d->parent->children.at(ii) == r->d()->d) {
if ((ii + 1) == r->d()->d->parent->children.count())
- return Encode::null();
+ scope.result = Encode::null();
else
- return Node::create(scope.engine, r->d()->d->parent->children.at(ii + 1));
+ scope.result = Node::create(scope.engine, r->d()->d->parent->children.at(ii + 1));
+ return;
}
}
- return Encode::null();
+ scope.result = Encode::null();
}
-ReturnedValue NodePrototype::method_get_attributes(CallContext *ctx)
+void NodePrototype::method_get_attributes(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
if (r->d()->d->type != NodeImpl::Element)
- return Encode::null();
+ scope.result = Encode::null();
else
- return NamedNodeMap::create(scope.engine, r->d()->d, r->d()->d->attributes);
+ scope.result = NamedNodeMap::create(scope.engine, r->d()->d, r->d()->d->attributes);
}
ReturnedValue NodePrototype::getProto(ExecutionEngine *v4)
@@ -666,44 +659,40 @@ ReturnedValue Attr::prototype(ExecutionEngine *engine)
return d->attrPrototype.value();
}
-ReturnedValue Attr::method_name(CallContext *ctx)
+void Attr::method_name(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r)
- return Encode::undefined();
+ RETURN_UNDEFINED();
- return QV4::Encode(scope.engine->newString(r->d()->d->name));
+ scope.result = scope.engine->newString(r->d()->d->name);
}
-ReturnedValue Attr::method_value(CallContext *ctx)
+void Attr::method_value(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r)
- return Encode::undefined();
+ RETURN_UNDEFINED();
- return QV4::Encode(scope.engine->newString(r->d()->d->data));
+ scope.result = scope.engine->newString(r->d()->d->data);
}
-ReturnedValue Attr::method_ownerElement(CallContext *ctx)
+void Attr::method_ownerElement(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r)
- return Encode::undefined();
+ RETURN_UNDEFINED();
- return Node::create(scope.engine, r->d()->d->parent);
+ scope.result = Node::create(scope.engine, r->d()->d->parent);
}
-ReturnedValue CharacterData::method_length(CallContext *ctx)
+void CharacterData::method_length(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r)
- return Encode::undefined();
+ RETURN_UNDEFINED();
- return Encode(r->d()->d->data.length());
+ scope.result = Encode(r->d()->d->data.length());
}
ReturnedValue CharacterData::prototype(ExecutionEngine *v4)
@@ -722,23 +711,22 @@ ReturnedValue CharacterData::prototype(ExecutionEngine *v4)
return d->characterDataPrototype.value();
}
-ReturnedValue Text::method_isElementContentWhitespace(CallContext *ctx)
+void Text::method_isElementContentWhitespace(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
- if (!r) return Encode::undefined();
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
+ if (!r)
+ RETURN_UNDEFINED();
- return Encode(QStringRef(&r->d()->d->data).trimmed().isEmpty());
+ scope.result = Encode(QStringRef(&r->d()->d->data).trimmed().isEmpty());
}
-ReturnedValue Text::method_wholeText(CallContext *ctx)
+void Text::method_wholeText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r)
- return Encode::undefined();
+ RETURN_UNDEFINED();
- return QV4::Encode(scope.engine->newString(r->d()->d->data));
+ scope.result = scope.engine->newString(r->d()->d->data);
}
ReturnedValue Text::prototype(ExecutionEngine *v4)
@@ -964,44 +952,40 @@ ReturnedValue NodeList::create(ExecutionEngine *v4, NodeImpl *data)
return (v4->memoryManager->allocObject<NodeList>(data))->asReturnedValue();
}
-ReturnedValue Document::method_documentElement(CallContext *ctx)
+void Document::method_documentElement(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r || r->d()->d->type != NodeImpl::Document)
- return Encode::undefined();
+ RETURN_UNDEFINED();
- return Node::create(scope.engine, static_cast<DocumentImpl *>(r->d()->d)->root);
+ scope.result = Node::create(scope.engine, static_cast<DocumentImpl *>(r->d()->d)->root);
}
-ReturnedValue Document::method_xmlStandalone(CallContext *ctx)
+void Document::method_xmlStandalone(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r || r->d()->d->type != NodeImpl::Document)
- return Encode::undefined();
+ RETURN_UNDEFINED();
- return Encode(static_cast<DocumentImpl *>(r->d()->d)->isStandalone);
+ scope.result = Encode(static_cast<DocumentImpl *>(r->d()->d)->isStandalone);
}
-ReturnedValue Document::method_xmlVersion(CallContext *ctx)
+void Document::method_xmlVersion(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r || r->d()->d->type != NodeImpl::Document)
- return Encode::undefined();
+ RETURN_UNDEFINED();
- return QV4::Encode(scope.engine->newString(static_cast<DocumentImpl *>(r->d()->d)->version));
+ scope.result = scope.engine->newString(static_cast<DocumentImpl *>(r->d()->d)->version);
}
-ReturnedValue Document::method_xmlEncoding(CallContext *ctx)
+void Document::method_xmlEncoding(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<Node> r(scope, ctx->thisObject().as<Node>());
+ Scoped<Node> r(scope, callData->thisObject.as<Node>());
if (!r || r->d()->d->type != NodeImpl::Document)
- return Encode::undefined();
+ RETURN_UNDEFINED();
- return QV4::Encode(scope.engine->newString(static_cast<DocumentImpl *>(r->d()->d)->encoding));
+ scope.result = scope.engine->newString(static_cast<DocumentImpl *>(r->d()->d)->encoding);
}
class QQmlXMLHttpRequest : public QObject
@@ -1657,21 +1641,21 @@ struct QQmlXMLHttpRequestCtor : public FunctionObject
void setupProto();
- static ReturnedValue method_open(CallContext *ctx);
- static ReturnedValue method_setRequestHeader(CallContext *ctx);
- static ReturnedValue method_send(CallContext *ctx);
- static ReturnedValue method_abort(CallContext *ctx);
- static ReturnedValue method_getResponseHeader(CallContext *ctx);
- static ReturnedValue method_getAllResponseHeaders(CallContext *ctx);
-
- static ReturnedValue method_get_readyState(CallContext *ctx);
- static ReturnedValue method_get_status(CallContext *ctx);
- static ReturnedValue method_get_statusText(CallContext *ctx);
- static ReturnedValue method_get_responseText(CallContext *ctx);
- static ReturnedValue method_get_responseXML(CallContext *ctx);
- static ReturnedValue method_get_response(CallContext *ctx);
- static ReturnedValue method_get_responseType(CallContext *ctx);
- static ReturnedValue method_set_responseType(CallContext *ctx);
+ static void method_open(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_setRequestHeader(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_send(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_abort(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_getResponseHeader(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_getAllResponseHeaders(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+
+ static void method_get_readyState(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_status(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_statusText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_responseText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_responseXML(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_response(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_responseType(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_set_responseType(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
};
}
@@ -1733,19 +1717,18 @@ void QQmlXMLHttpRequestCtor::setupProto()
// XMLHttpRequest methods
-ReturnedValue QQmlXMLHttpRequestCtor::method_open(CallContext *ctx)
+void QQmlXMLHttpRequestCtor::method_open(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
- if (ctx->argc() < 2 || ctx->argc() > 5)
- V4THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count");
+ if (callData->argc < 2 || callData->argc > 5)
+ THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count");
// Argument 0 - Method
- QString method = ctx->args()[0].toQStringNoThrow().toUpper();
+ QString method = callData->args[0].toQStringNoThrow().toUpper();
if (method != QLatin1String("GET") &&
method != QLatin1String("PUT") &&
method != QLatin1String("HEAD") &&
@@ -1754,26 +1737,26 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_open(CallContext *ctx)
method != QLatin1String("OPTIONS") &&
method != QLatin1String("PROPFIND") &&
method != QLatin1String("PATCH"))
- V4THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Unsupported HTTP method type");
+ THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Unsupported HTTP method type");
// Argument 1 - URL
- QUrl url = QUrl(ctx->args()[1].toQStringNoThrow());
+ QUrl url = QUrl(callData->args[1].toQStringNoThrow());
if (url.isRelative())
url = scope.engine->callingQmlContext()->resolvedUrl(url);
bool async = true;
// Argument 2 - async (optional)
- if (ctx->argc() > 2) {
- async = ctx->args()[2].booleanValue();
+ if (callData->argc > 2) {
+ async = callData->args[2].booleanValue();
}
// Argument 3/4 - user/pass (optional)
QString username, password;
- if (ctx->argc() > 3)
- username = ctx->args()[3].toQStringNoThrow();
- if (ctx->argc() > 4)
- password = ctx->args()[4].toQStringNoThrow();
+ if (callData->argc > 3)
+ username = callData->args[3].toQStringNoThrow();
+ if (callData->argc > 4)
+ password = callData->args[4].toQStringNoThrow();
// Clear the fragment (if any)
url.setFragment(QString());
@@ -1782,25 +1765,24 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_open(CallContext *ctx)
if (!username.isNull()) url.setUserName(username);
if (!password.isNull()) url.setPassword(password);
- return r->open(w, scope.engine->callingQmlContext(), method, url, async ? QQmlXMLHttpRequest::AsynchronousLoad : QQmlXMLHttpRequest::SynchronousLoad);
+ scope.result = r->open(w, scope.engine->callingQmlContext(), method, url, async ? QQmlXMLHttpRequest::AsynchronousLoad : QQmlXMLHttpRequest::SynchronousLoad);
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_setRequestHeader(CallContext *ctx)
+void QQmlXMLHttpRequestCtor::method_setRequestHeader(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
- if (ctx->argc() != 2)
- V4THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count");
+ if (callData->argc != 2)
+ THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count");
if (r->readyState() != QQmlXMLHttpRequest::Opened || r->sendFlag())
- V4THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
+ THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
- QString name = ctx->args()[0].toQStringNoThrow();
- QString value = ctx->args()[1].toQStringNoThrow();
+ QString name = callData->args[0].toQStringNoThrow();
+ QString value = callData->args[1].toQStringNoThrow();
// ### Check that name and value are well formed
@@ -1825,148 +1807,139 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_setRequestHeader(CallContext *ctx)
nameUpper == QLatin1String("VIA") ||
nameUpper.startsWith(QLatin1String("PROXY-")) ||
nameUpper.startsWith(QLatin1String("SEC-")))
- return Encode::undefined();
+ RETURN_UNDEFINED();
r->addHeader(name, value);
- return Encode::undefined();
+ RETURN_UNDEFINED();
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_send(CallContext *ctx)
+void QQmlXMLHttpRequestCtor::method_send(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
if (r->readyState() != QQmlXMLHttpRequest::Opened ||
r->sendFlag())
- V4THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
+ THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
QByteArray data;
- if (ctx->argc() > 0)
- data = ctx->args()[0].toQStringNoThrow().toUtf8();
+ if (callData->argc > 0)
+ data = callData->args[0].toQStringNoThrow().toUtf8();
- return r->send(w, scope.engine->callingQmlContext(), data);
+ scope.result = r->send(w, scope.engine->callingQmlContext(), data);
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_abort(CallContext *ctx)
+void QQmlXMLHttpRequestCtor::method_abort(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
- return r->abort(w, scope.engine->callingQmlContext());
+ scope.result = r->abort(w, scope.engine->callingQmlContext());
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_getResponseHeader(CallContext *ctx)
+void QQmlXMLHttpRequestCtor::method_getResponseHeader(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
- if (ctx->argc() != 1)
- V4THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count");
+ if (callData->argc != 1)
+ THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count");
if (r->readyState() != QQmlXMLHttpRequest::Loading &&
r->readyState() != QQmlXMLHttpRequest::Done &&
r->readyState() != QQmlXMLHttpRequest::HeadersReceived)
- V4THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
+ THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
- return QV4::Encode(scope.engine->newString(r->header(ctx->args()[0].toQStringNoThrow())));
+ scope.result = scope.engine->newString(r->header(callData->args[0].toQStringNoThrow()));
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_getAllResponseHeaders(CallContext *ctx)
+void QQmlXMLHttpRequestCtor::method_getAllResponseHeaders(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
- if (ctx->argc() != 0)
- V4THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count");
+ if (callData->argc != 0)
+ THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count");
if (r->readyState() != QQmlXMLHttpRequest::Loading &&
r->readyState() != QQmlXMLHttpRequest::Done &&
r->readyState() != QQmlXMLHttpRequest::HeadersReceived)
- V4THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
+ THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
- return QV4::Encode(scope.engine->newString(r->headers()));
+ scope.result = scope.engine->newString(r->headers());
}
// XMLHttpRequest properties
-ReturnedValue QQmlXMLHttpRequestCtor::method_get_readyState(CallContext *ctx)
+void QQmlXMLHttpRequestCtor::method_get_readyState(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
- return Encode(r->readyState());
+ scope.result = Encode(r->readyState());
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_get_status(CallContext *ctx)
+void QQmlXMLHttpRequestCtor::method_get_status(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
if (r->readyState() == QQmlXMLHttpRequest::Unsent ||
r->readyState() == QQmlXMLHttpRequest::Opened)
- V4THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
+ THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
if (r->errorFlag())
- return Encode(0);
+ scope.result = Encode(0);
else
- return Encode(r->replyStatus());
+ scope.result = Encode(r->replyStatus());
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_get_statusText(CallContext *ctx)
+void QQmlXMLHttpRequestCtor::method_get_statusText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
if (r->readyState() == QQmlXMLHttpRequest::Unsent ||
r->readyState() == QQmlXMLHttpRequest::Opened)
- V4THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
+ THROW_DOM(DOMEXCEPTION_INVALID_STATE_ERR, "Invalid state");
if (r->errorFlag())
- return QV4::Encode(scope.engine->newString(QString()));
+ scope.result = scope.engine->newString(QString());
else
- return QV4::Encode(scope.engine->newString(r->replyStatusText()));
+ scope.result = scope.engine->newString(r->replyStatusText());
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseText(CallContext *ctx)
+void QQmlXMLHttpRequestCtor::method_get_responseText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
if (r->readyState() != QQmlXMLHttpRequest::Loading &&
r->readyState() != QQmlXMLHttpRequest::Done)
- return QV4::Encode(scope.engine->newString(QString()));
+ scope.result = scope.engine->newString(QString());
else
- return QV4::Encode(scope.engine->newString(r->responseBody()));
+ scope.result = scope.engine->newString(r->responseBody());
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseXML(CallContext *ctx)
+void QQmlXMLHttpRequestCtor::method_get_responseXML(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
@@ -1974,66 +1947,63 @@ ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseXML(CallContext *ctx)
if (!r->receivedXml() ||
(r->readyState() != QQmlXMLHttpRequest::Loading &&
r->readyState() != QQmlXMLHttpRequest::Done)) {
- return Encode::null();
+ scope.result = Encode::null();
} else {
if (r->responseType().isEmpty())
r->setResponseType(QLatin1String("document"));
- return r->xmlResponseBody(scope.engine);
+ scope.result = r->xmlResponseBody(scope.engine);
}
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_get_response(CallContext *ctx)
+void QQmlXMLHttpRequestCtor::method_get_response(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
if (r->readyState() != QQmlXMLHttpRequest::Loading &&
r->readyState() != QQmlXMLHttpRequest::Done)
- return QV4::Encode(scope.engine->newString(QString()));
+ RETURN_RESULT(scope.engine->newString(QString()));
const QString& responseType = r->responseType();
if (responseType.compare(QLatin1String("text"), Qt::CaseInsensitive) == 0 || responseType.isEmpty()) {
- return QV4::Encode(scope.engine->newString(r->responseBody()));
+ RETURN_RESULT(scope.engine->newString(r->responseBody()));
} else if (responseType.compare(QLatin1String("arraybuffer"), Qt::CaseInsensitive) == 0) {
- return QV4::Encode(scope.engine->newArrayBuffer(r->rawResponseBody()));
+ RETURN_RESULT(scope.engine->newArrayBuffer(r->rawResponseBody()));
} else if (responseType.compare(QLatin1String("json"), Qt::CaseInsensitive) == 0) {
- return r->jsonResponseBody(scope.engine);
+ RETURN_RESULT(r->jsonResponseBody(scope.engine));
} else if (responseType.compare(QLatin1String("document"), Qt::CaseInsensitive) == 0) {
- return r->xmlResponseBody(scope.engine);
+ RETURN_RESULT(r->xmlResponseBody(scope.engine));
} else {
- return QV4::Encode(scope.engine->newString(QString()));
+ RETURN_RESULT(scope.engine->newString(QString()));
}
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_get_responseType(CallContext *ctx)
+void QQmlXMLHttpRequestCtor::method_get_responseType(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
- return QV4::Encode(scope.engine->newString(r->responseType()));
+ scope.result = scope.engine->newString(r->responseType());
}
-ReturnedValue QQmlXMLHttpRequestCtor::method_set_responseType(CallContext *ctx)
+void QQmlXMLHttpRequestCtor::method_set_responseType(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- Scope scope(ctx);
- Scoped<QQmlXMLHttpRequestWrapper> w(scope, ctx->thisObject().as<QQmlXMLHttpRequestWrapper>());
+ Scoped<QQmlXMLHttpRequestWrapper> w(scope, callData->thisObject.as<QQmlXMLHttpRequestWrapper>());
if (!w)
V4THROW_REFERENCE("Not an XMLHttpRequest object");
QQmlXMLHttpRequest *r = w->d()->request;
- if (ctx->argc() < 1)
- V4THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count");
+ if (callData->argc < 1)
+ THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "Incorrect argument count");
// Argument 0 - response type
- r->setResponseType(ctx->args()[0].toQStringNoThrow());
+ r->setResponseType(callData->args[0].toQStringNoThrow());
- return Encode::undefined();
+ scope.result = Encode::undefined();
}
void qt_rem_qmlxmlhttprequest(ExecutionEngine * /* engine */, void *d)
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
index 19dc100f40..d359a0f62f 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp
@@ -85,6 +85,12 @@ using namespace QV4;
DEFINE_OBJECT_VTABLE(QtObject);
+#define THROW_TYPE_ERROR_WITH_MESSAGE(msg) \
+ do { \
+ scope.result = scope.engine->throwTypeError(QString::fromUtf8(msg)); \
+ return; \
+ } while (false)
+
struct StaticQtMetaObject : public QObject
{
static const QMetaObject *get()
@@ -223,12 +229,12 @@ void QtObject::advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint
\qmlmethod bool Qt::isQtObject(object)
Returns true if \c object is a valid reference to a Qt or QML object, otherwise false.
*/
-ReturnedValue QtObject::method_isQtObject(QV4::CallContext *ctx)
+void QtObject::method_isQtObject(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() == 0)
- return QV4::Encode(false);
+ if (callData->argc == 0)
+ RETURN_RESULT(QV4::Encode(false));
- return QV4::Encode(ctx->args()[0].as<QV4::QObjectWrapper>() != 0);
+ scope.result = QV4::Encode(callData->args[0].as<QV4::QObjectWrapper>() != 0);
}
/*!
@@ -237,16 +243,16 @@ ReturnedValue QtObject::method_isQtObject(QV4::CallContext *ctx)
Returns a color with the specified \c red, \c green, \c blue and \c alpha components.
All components should be in the range 0-1 inclusive.
*/
-ReturnedValue QtObject::method_rgba(QV4::CallContext *ctx)
+void QtObject::method_rgba(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- int argCount = ctx->argc();
+ int argCount = callData->argc;
if (argCount < 3 || argCount > 4)
- V4THROW_ERROR("Qt.rgba(): Invalid arguments");
+ THROW_GENERIC_ERROR("Qt.rgba(): Invalid arguments");
- double r = ctx->args()[0].toNumber();
- double g = ctx->args()[1].toNumber();
- double b = ctx->args()[2].toNumber();
- double a = (argCount == 4) ? ctx->args()[3].toNumber() : 1;
+ double r = callData->args[0].toNumber();
+ double g = callData->args[1].toNumber();
+ double b = callData->args[2].toNumber();
+ double a = (argCount == 4) ? callData->args[3].toNumber() : 1;
if (r < 0.0) r=0.0;
if (r > 1.0) r=1.0;
@@ -257,7 +263,7 @@ ReturnedValue QtObject::method_rgba(QV4::CallContext *ctx)
if (a < 0.0) a=0.0;
if (a > 1.0) a=1.0;
- return ctx->engine()->fromVariant(QQml_colorProvider()->fromRgbF(r, g, b, a));
+ scope.result = scope.engine->fromVariant(QQml_colorProvider()->fromRgbF(r, g, b, a));
}
/*!
@@ -266,16 +272,16 @@ ReturnedValue QtObject::method_rgba(QV4::CallContext *ctx)
Returns a color with the specified \c hue, \c saturation, \c lightness and \c alpha components.
All components should be in the range 0-1 inclusive.
*/
-ReturnedValue QtObject::method_hsla(QV4::CallContext *ctx)
+void QtObject::method_hsla(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- int argCount = ctx->argc();
+ int argCount = callData->argc;
if (argCount < 3 || argCount > 4)
- V4THROW_ERROR("Qt.hsla(): Invalid arguments");
+ THROW_GENERIC_ERROR("Qt.hsla(): Invalid arguments");
- double h = ctx->args()[0].toNumber();
- double s = ctx->args()[1].toNumber();
- double l = ctx->args()[2].toNumber();
- double a = (argCount == 4) ? ctx->args()[3].toNumber() : 1;
+ double h = callData->args[0].toNumber();
+ double s = callData->args[1].toNumber();
+ double l = callData->args[2].toNumber();
+ double a = (argCount == 4) ? callData->args[3].toNumber() : 1;
if (h < 0.0) h=0.0;
if (h > 1.0) h=1.0;
@@ -286,7 +292,7 @@ ReturnedValue QtObject::method_hsla(QV4::CallContext *ctx)
if (a < 0.0) a=0.0;
if (a > 1.0) a=1.0;
- return ctx->engine()->fromVariant(QQml_colorProvider()->fromHslF(h, s, l, a));
+ scope.result = scope.engine->fromVariant(QQml_colorProvider()->fromHslF(h, s, l, a));
}
/*!
@@ -297,23 +303,23 @@ All components should be in the range 0-1 inclusive.
\since 5.5
*/
-ReturnedValue QtObject::method_hsva(QV4::CallContext *ctx)
+void QtObject::method_hsva(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- int argCount = ctx->argc();
+ int argCount = callData->argc;
if (argCount < 3 || argCount > 4)
- V4THROW_ERROR("Qt.hsva(): Invalid arguments");
+ THROW_GENERIC_ERROR("Qt.hsva(): Invalid arguments");
- double h = ctx->args()[0].toNumber();
- double s = ctx->args()[1].toNumber();
- double v = ctx->args()[2].toNumber();
- double a = (argCount == 4) ? ctx->args()[3].toNumber() : 1;
+ double h = callData->args[0].toNumber();
+ double s = callData->args[1].toNumber();
+ double v = callData->args[2].toNumber();
+ double a = (argCount == 4) ? callData->args[3].toNumber() : 1;
h = qBound(0.0, h, 1.0);
s = qBound(0.0, s, 1.0);
v = qBound(0.0, v, 1.0);
a = qBound(0.0, a, 1.0);
- return ctx->engine()->fromVariant(QQml_colorProvider()->fromHsvF(h, s, v, a));
+ scope.result = scope.engine->fromVariant(QQml_colorProvider()->fromHsvF(h, s, v, a));
}
/*!
@@ -324,35 +330,35 @@ may be either color values or string values. If a string value is supplied it
must be convertible to a color, as described for the \l{colorbasictypedocs}{color}
basic type.
*/
-ReturnedValue QtObject::method_colorEqual(QV4::CallContext *ctx)
+void QtObject::method_colorEqual(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 2)
- V4THROW_ERROR("Qt.colorEqual(): Invalid arguments");
+ if (callData->argc != 2)
+ THROW_GENERIC_ERROR("Qt.colorEqual(): Invalid arguments");
bool ok = false;
- QVariant lhs = ctx->d()->engine->toVariant(ctx->args()[0], -1);
+ QVariant lhs = scope.engine->toVariant(callData->args[0], -1);
if (lhs.userType() == QVariant::String) {
lhs = QQmlStringConverters::colorFromString(lhs.toString(), &ok);
if (!ok) {
- V4THROW_ERROR("Qt.colorEqual(): Invalid color name");
+ THROW_GENERIC_ERROR("Qt.colorEqual(): Invalid color name");
}
} else if (lhs.userType() != QVariant::Color) {
- V4THROW_ERROR("Qt.colorEqual(): Invalid arguments");
+ THROW_GENERIC_ERROR("Qt.colorEqual(): Invalid arguments");
}
- QVariant rhs = ctx->engine()->toVariant(ctx->args()[1], -1);
+ QVariant rhs = scope.engine->toVariant(callData->args[1], -1);
if (rhs.userType() == QVariant::String) {
rhs = QQmlStringConverters::colorFromString(rhs.toString(), &ok);
if (!ok) {
- V4THROW_ERROR("Qt.colorEqual(): Invalid color name");
+ THROW_GENERIC_ERROR("Qt.colorEqual(): Invalid color name");
}
} else if (rhs.userType() != QVariant::Color) {
- V4THROW_ERROR("Qt.colorEqual(): Invalid arguments");
+ THROW_GENERIC_ERROR("Qt.colorEqual(): Invalid arguments");
}
bool equal = (lhs == rhs);
- return QV4::Encode(equal);
+ scope.result = QV4::Encode(equal);
}
/*!
@@ -362,47 +368,47 @@ Returns a \c rect with the top-left corner at \c x, \c y and the specified \c wi
The returned object has \c x, \c y, \c width and \c height attributes with the given values.
*/
-ReturnedValue QtObject::method_rect(QV4::CallContext *ctx)
+void QtObject::method_rect(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 4)
- V4THROW_ERROR("Qt.rect(): Invalid arguments");
+ if (callData->argc != 4)
+ THROW_GENERIC_ERROR("Qt.rect(): Invalid arguments");
- double x = ctx->args()[0].toNumber();
- double y = ctx->args()[1].toNumber();
- double w = ctx->args()[2].toNumber();
- double h = ctx->args()[3].toNumber();
+ double x = callData->args[0].toNumber();
+ double y = callData->args[1].toNumber();
+ double w = callData->args[2].toNumber();
+ double h = callData->args[3].toNumber();
- return ctx->engine()->fromVariant(QVariant::fromValue(QRectF(x, y, w, h)));
+ scope.result = scope.engine->fromVariant(QVariant::fromValue(QRectF(x, y, w, h)));
}
/*!
\qmlmethod point Qt::point(int x, int y)
Returns a Point with the specified \c x and \c y coordinates.
*/
-ReturnedValue QtObject::method_point(QV4::CallContext *ctx)
+void QtObject::method_point(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 2)
- V4THROW_ERROR("Qt.point(): Invalid arguments");
+ if (callData->argc != 2)
+ THROW_GENERIC_ERROR("Qt.point(): Invalid arguments");
- double x = ctx->args()[0].toNumber();
- double y = ctx->args()[1].toNumber();
+ double x = callData->args[0].toNumber();
+ double y = callData->args[1].toNumber();
- return ctx->engine()->fromVariant(QVariant::fromValue(QPointF(x, y)));
+ scope.result = scope.engine->fromVariant(QVariant::fromValue(QPointF(x, y)));
}
/*!
\qmlmethod Qt::size(int width, int height)
Returns a Size with the specified \c width and \c height.
*/
-ReturnedValue QtObject::method_size(QV4::CallContext *ctx)
+void QtObject::method_size(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 2)
- V4THROW_ERROR("Qt.size(): Invalid arguments");
+ if (callData->argc != 2)
+ THROW_GENERIC_ERROR("Qt.size(): Invalid arguments");
- double w = ctx->args()[0].toNumber();
- double h = ctx->args()[1].toNumber();
+ double w = callData->args[0].toNumber();
+ double h = callData->args[1].toNumber();
- return ctx->engine()->fromVariant(QVariant::fromValue(QSizeF(w, h)));
+ scope.result = scope.engine->fromVariant(QVariant::fromValue(QSizeF(w, h)));
}
/*!
@@ -413,17 +419,17 @@ key-value pairs where valid keys are the \l{fontbasictypedocs}{font} type's
subproperty names, and the values are valid values for each subproperty.
Invalid keys will be ignored.
*/
-ReturnedValue QtObject::method_font(QV4::CallContext *ctx)
+void QtObject::method_font(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 1 || !ctx->args()[0].isObject())
- V4THROW_ERROR("Qt.font(): Invalid arguments");
+ if (callData->argc != 1 || !callData->args[0].isObject())
+ THROW_GENERIC_ERROR("Qt.font(): Invalid arguments");
- QV4::ExecutionEngine *v4 = ctx->d()->engine;
+ QV4::ExecutionEngine *v4 = scope.engine;
bool ok = false;
- QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QFont, QQmlV4Handle(ctx->args()[0]), v4, &ok);
+ QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QFont, QQmlV4Handle(callData->args[0]), v4, &ok);
if (!ok)
- V4THROW_ERROR("Qt.font(): Invalid argument: no valid font subproperties specified");
- return ctx->engine()->fromVariant(v);
+ THROW_GENERIC_ERROR("Qt.font(): Invalid argument: no valid font subproperties specified");
+ scope.result = scope.engine->fromVariant(v);
}
@@ -432,73 +438,73 @@ ReturnedValue QtObject::method_font(QV4::CallContext *ctx)
\qmlmethod Qt::vector2d(real x, real y)
Returns a Vector2D with the specified \c x and \c y.
*/
-ReturnedValue QtObject::method_vector2d(QV4::CallContext *ctx)
+void QtObject::method_vector2d(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 2)
- V4THROW_ERROR("Qt.vector2d(): Invalid arguments");
+ if (callData->argc != 2)
+ THROW_GENERIC_ERROR("Qt.vector2d(): Invalid arguments");
float xy[3]; // qvector2d uses float internally
- xy[0] = ctx->args()[0].toNumber();
- xy[1] = ctx->args()[1].toNumber();
+ xy[0] = callData->args[0].toNumber();
+ xy[1] = callData->args[1].toNumber();
const void *params[] = { xy };
- return ctx->engine()->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector2D, 1, params));
+ scope.result = scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector2D, 1, params));
}
/*!
\qmlmethod Qt::vector3d(real x, real y, real z)
Returns a Vector3D with the specified \c x, \c y and \c z.
*/
-ReturnedValue QtObject::method_vector3d(QV4::CallContext *ctx)
+void QtObject::method_vector3d(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 3)
- V4THROW_ERROR("Qt.vector3d(): Invalid arguments");
+ if (callData->argc != 3)
+ THROW_GENERIC_ERROR("Qt.vector3d(): Invalid arguments");
float xyz[3]; // qvector3d uses float internally
- xyz[0] = ctx->args()[0].toNumber();
- xyz[1] = ctx->args()[1].toNumber();
- xyz[2] = ctx->args()[2].toNumber();
+ xyz[0] = callData->args[0].toNumber();
+ xyz[1] = callData->args[1].toNumber();
+ xyz[2] = callData->args[2].toNumber();
const void *params[] = { xyz };
- return ctx->engine()->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector3D, 1, params));
+ scope.result = scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector3D, 1, params));
}
/*!
\qmlmethod Qt::vector4d(real x, real y, real z, real w)
Returns a Vector4D with the specified \c x, \c y, \c z and \c w.
*/
-ReturnedValue QtObject::method_vector4d(QV4::CallContext *ctx)
+void QtObject::method_vector4d(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 4)
- V4THROW_ERROR("Qt.vector4d(): Invalid arguments");
+ if (callData->argc != 4)
+ THROW_GENERIC_ERROR("Qt.vector4d(): Invalid arguments");
float xyzw[4]; // qvector4d uses float internally
- xyzw[0] = ctx->args()[0].toNumber();
- xyzw[1] = ctx->args()[1].toNumber();
- xyzw[2] = ctx->args()[2].toNumber();
- xyzw[3] = ctx->args()[3].toNumber();
+ xyzw[0] = callData->args[0].toNumber();
+ xyzw[1] = callData->args[1].toNumber();
+ xyzw[2] = callData->args[2].toNumber();
+ xyzw[3] = callData->args[3].toNumber();
const void *params[] = { xyzw };
- return ctx->engine()->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector4D, 1, params));
+ scope.result = scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QVector4D, 1, params));
}
/*!
\qmlmethod Qt::quaternion(real scalar, real x, real y, real z)
Returns a Quaternion with the specified \c scalar, \c x, \c y, and \c z.
*/
-ReturnedValue QtObject::method_quaternion(QV4::CallContext *ctx)
+void QtObject::method_quaternion(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 4)
- V4THROW_ERROR("Qt.quaternion(): Invalid arguments");
+ if (callData->argc != 4)
+ THROW_GENERIC_ERROR("Qt.quaternion(): Invalid arguments");
qreal sxyz[4]; // qquaternion uses qreal internally
- sxyz[0] = ctx->args()[0].toNumber();
- sxyz[1] = ctx->args()[1].toNumber();
- sxyz[2] = ctx->args()[2].toNumber();
- sxyz[3] = ctx->args()[3].toNumber();
+ sxyz[0] = callData->args[0].toNumber();
+ sxyz[1] = callData->args[1].toNumber();
+ sxyz[2] = callData->args[2].toNumber();
+ sxyz[3] = callData->args[3].toNumber();
const void *params[] = { sxyz };
- return ctx->engine()->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QQuaternion, 1, params));
+ scope.result = scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QQuaternion, 1, params));
}
/*!
@@ -510,44 +516,47 @@ matrix values.
Finally, the function may be called with no arguments and the resulting
matrix will be the identity matrix.
*/
-ReturnedValue QtObject::method_matrix4x4(QV4::CallContext *ctx)
+void QtObject::method_matrix4x4(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- QV4::ExecutionEngine *v4 = ctx->d()->engine;
+ QV4::ExecutionEngine *v4 = scope.engine;
- if (ctx->argc() == 0)
- return ctx->engine()->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, 0, Q_NULLPTR));
+ if (callData->argc == 0) {
+ scope.result = scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, 0, Q_NULLPTR));
+ return;
+ }
- if (ctx->argc() == 1 && ctx->args()[0].isObject()) {
+ if (callData->argc == 1 && callData->args[0].isObject()) {
bool ok = false;
- QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QMatrix4x4, QQmlV4Handle(ctx->args()[0]), v4, &ok);
+ QVariant v = QQml_valueTypeProvider()->createVariantFromJsObject(QMetaType::QMatrix4x4, QQmlV4Handle(callData->args[0]), v4, &ok);
if (!ok)
- V4THROW_ERROR("Qt.matrix4x4(): Invalid argument: not a valid matrix4x4 values array");
- return ctx->engine()->fromVariant(v);
+ THROW_GENERIC_ERROR("Qt.matrix4x4(): Invalid argument: not a valid matrix4x4 values array");
+ scope.result = scope.engine->fromVariant(v);
+ return;
}
- if (ctx->argc() != 16)
- V4THROW_ERROR("Qt.matrix4x4(): Invalid arguments");
+ if (callData->argc != 16)
+ THROW_GENERIC_ERROR("Qt.matrix4x4(): Invalid arguments");
qreal vals[16]; // qmatrix4x4 uses qreal internally
- vals[0] = ctx->args()[0].toNumber();
- vals[1] = ctx->args()[1].toNumber();
- vals[2] = ctx->args()[2].toNumber();
- vals[3] = ctx->args()[3].toNumber();
- vals[4] = ctx->args()[4].toNumber();
- vals[5] = ctx->args()[5].toNumber();
- vals[6] = ctx->args()[6].toNumber();
- vals[7] = ctx->args()[7].toNumber();
- vals[8] = ctx->args()[8].toNumber();
- vals[9] = ctx->args()[9].toNumber();
- vals[10] = ctx->args()[10].toNumber();
- vals[11] = ctx->args()[11].toNumber();
- vals[12] = ctx->args()[12].toNumber();
- vals[13] = ctx->args()[13].toNumber();
- vals[14] = ctx->args()[14].toNumber();
- vals[15] = ctx->args()[15].toNumber();
+ vals[0] = callData->args[0].toNumber();
+ vals[1] = callData->args[1].toNumber();
+ vals[2] = callData->args[2].toNumber();
+ vals[3] = callData->args[3].toNumber();
+ vals[4] = callData->args[4].toNumber();
+ vals[5] = callData->args[5].toNumber();
+ vals[6] = callData->args[6].toNumber();
+ vals[7] = callData->args[7].toNumber();
+ vals[8] = callData->args[8].toNumber();
+ vals[9] = callData->args[9].toNumber();
+ vals[10] = callData->args[10].toNumber();
+ vals[11] = callData->args[11].toNumber();
+ vals[12] = callData->args[12].toNumber();
+ vals[13] = callData->args[13].toNumber();
+ vals[14] = callData->args[14].toNumber();
+ vals[15] = callData->args[15].toNumber();
const void *params[] = { vals };
- return ctx->engine()->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, 1, params));
+ scope.result = scope.engine->fromVariant(QQml_valueTypeProvider()->createValueType(QMetaType::QMatrix4x4, 1, params));
}
/*!
@@ -564,27 +573,29 @@ by factor and converts the color back to RGB.
If \c factor is not supplied, returns a color 50% lighter than \c baseColor (factor 1.5).
*/
-ReturnedValue QtObject::method_lighter(QV4::CallContext *ctx)
+void QtObject::method_lighter(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 1 && ctx->argc() != 2)
- V4THROW_ERROR("Qt.lighter(): Invalid arguments");
+ if (callData->argc != 1 && callData->argc != 2)
+ THROW_GENERIC_ERROR("Qt.lighter(): Invalid arguments");
- QVariant v = ctx->engine()->toVariant(ctx->args()[0], -1);
+ QVariant v = scope.engine->toVariant(callData->args[0], -1);
if (v.userType() == QVariant::String) {
bool ok = false;
v = QQmlStringConverters::colorFromString(v.toString(), &ok);
if (!ok) {
- return QV4::Encode::null();
+ scope.result = QV4::Encode::null();
+ return;
}
} else if (v.userType() != QVariant::Color) {
- return QV4::Encode::null();
+ scope.result = QV4::Encode::null();
+ return;
}
qreal factor = 1.5;
- if (ctx->argc() == 2)
- factor = ctx->args()[1].toNumber();
+ if (callData->argc == 2)
+ factor = callData->args[1].toNumber();
- return ctx->engine()->fromVariant(QQml_colorProvider()->lighter(v, factor));
+ scope.result = scope.engine->fromVariant(QQml_colorProvider()->lighter(v, factor));
}
/*!
@@ -602,27 +613,29 @@ by factor and converts the color back to RGB.
If \c factor is not supplied, returns a color 50% darker than \c baseColor (factor 2.0).
*/
-ReturnedValue QtObject::method_darker(QV4::CallContext *ctx)
+void QtObject::method_darker(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 1 && ctx->argc() != 2)
- V4THROW_ERROR("Qt.darker(): Invalid arguments");
+ if (callData->argc != 1 && callData->argc != 2)
+ THROW_GENERIC_ERROR("Qt.darker(): Invalid arguments");
- QVariant v = ctx->engine()->toVariant(ctx->args()[0], -1);
+ QVariant v = scope.engine->toVariant(callData->args[0], -1);
if (v.userType() == QVariant::String) {
bool ok = false;
v = QQmlStringConverters::colorFromString(v.toString(), &ok);
if (!ok) {
- return QV4::Encode::null();
+ scope.result = QV4::Encode::null();
+ return;
}
} else if (v.userType() != QVariant::Color) {
- return QV4::Encode::null();
+ scope.result = QV4::Encode::null();
+ return;
}
qreal factor = 2.0;
- if (ctx->argc() == 2)
- factor = ctx->args()[1].toNumber();
+ if (callData->argc == 2)
+ factor = callData->args[1].toNumber();
- return ctx->engine()->fromVariant(QQml_colorProvider()->darker(v, factor));
+ scope.result = scope.engine->fromVariant(QQml_colorProvider()->darker(v, factor));
}
/*!
@@ -649,36 +662,40 @@ ReturnedValue QtObject::method_darker(QV4::CallContext *ctx)
Tint is most useful when a subtle change is intended to be conveyed due to some event; you can then use tinting to more effectively tune the visible color.
*/
-ReturnedValue QtObject::method_tint(QV4::CallContext *ctx)
+void QtObject::method_tint(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 2)
- V4THROW_ERROR("Qt.tint(): Invalid arguments");
+ if (callData->argc != 2)
+ THROW_GENERIC_ERROR("Qt.tint(): Invalid arguments");
// base color
- QVariant v1 = ctx->engine()->toVariant(ctx->args()[0], -1);
+ QVariant v1 = scope.engine->toVariant(callData->args[0], -1);
if (v1.userType() == QVariant::String) {
bool ok = false;
v1 = QQmlStringConverters::colorFromString(v1.toString(), &ok);
if (!ok) {
- return QV4::Encode::null();
+ scope.result = QV4::Encode::null();
+ return;
}
} else if (v1.userType() != QVariant::Color) {
- return QV4::Encode::null();
+ scope.result = QV4::Encode::null();
+ return;
}
// tint color
- QVariant v2 = ctx->engine()->toVariant(ctx->args()[1], -1);
+ QVariant v2 = scope.engine->toVariant(callData->args[1], -1);
if (v2.userType() == QVariant::String) {
bool ok = false;
v2 = QQmlStringConverters::colorFromString(v2.toString(), &ok);
if (!ok) {
- return QV4::Encode::null();
+ scope.result = QV4::Encode::null();
+ return;
}
} else if (v2.userType() != QVariant::Color) {
- return QV4::Encode::null();
+ scope.result = QV4::Encode::null();
+ return;
}
- return ctx->engine()->fromVariant(QQml_colorProvider()->tint(v1, v2));
+ scope.result = scope.engine->fromVariant(QQml_colorProvider()->tint(v1, v2));
}
/*!
@@ -697,32 +714,31 @@ If \a format is not specified, \a date is formatted using
\sa Locale
*/
-ReturnedValue QtObject::method_formatDate(QV4::CallContext *ctx)
+void QtObject::method_formatDate(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() < 1 || ctx->argc() > 2)
- V4THROW_ERROR("Qt.formatDate(): Invalid arguments");
- QV4::Scope scope(ctx);
+ if (callData->argc < 1 || callData->argc > 2)
+ THROW_GENERIC_ERROR("Qt.formatDate(): Invalid arguments");
Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
- QDate date = ctx->engine()->toVariant(ctx->args()[0], -1).toDateTime().date();
+ QDate date = scope.engine->toVariant(callData->args[0], -1).toDateTime().date();
QString formattedDate;
- if (ctx->argc() == 2) {
- QV4::ScopedString s(scope, ctx->args()[1]);
+ if (callData->argc == 2) {
+ QV4::ScopedString s(scope, callData->args[1]);
if (s) {
QString format = s->toQString();
formattedDate = date.toString(format);
- } else if (ctx->args()[1].isNumber()) {
- quint32 intFormat = ctx->args()[1].asDouble();
+ } else if (callData->args[1].isNumber()) {
+ quint32 intFormat = callData->args[1].asDouble();
Qt::DateFormat format = Qt::DateFormat(intFormat);
formattedDate = date.toString(format);
} else {
- V4THROW_ERROR("Qt.formatDate(): Invalid date format");
+ THROW_GENERIC_ERROR("Qt.formatDate(): Invalid date format");
}
} else {
formattedDate = date.toString(enumFormat);
}
- return ctx->d()->engine->newString(formattedDate)->asReturnedValue();
+ scope.result = scope.engine->newString(formattedDate);
}
/*!
@@ -740,38 +756,37 @@ If \a format is not specified, \a time is formatted using
\sa Locale
*/
-ReturnedValue QtObject::method_formatTime(QV4::CallContext *ctx)
+void QtObject::method_formatTime(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() < 1 || ctx->argc() > 2)
- V4THROW_ERROR("Qt.formatTime(): Invalid arguments");
- QV4::Scope scope(ctx);
+ if (callData->argc < 1 || callData->argc > 2)
+ THROW_GENERIC_ERROR("Qt.formatTime(): Invalid arguments");
- QVariant argVariant = ctx->engine()->toVariant(ctx->args()[0], -1);
+ QVariant argVariant = scope.engine->toVariant(callData->args[0], -1);
QTime time;
- if (ctx->args()[0].as<DateObject>() || (argVariant.type() == QVariant::String))
+ if (callData->args[0].as<DateObject>() || (argVariant.type() == QVariant::String))
time = argVariant.toDateTime().time();
else // if (argVariant.type() == QVariant::Time), or invalid.
time = argVariant.toTime();
Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
QString formattedTime;
- if (ctx->argc() == 2) {
- QV4::ScopedString s(scope, ctx->args()[1]);
+ if (callData->argc == 2) {
+ QV4::ScopedString s(scope, callData->args[1]);
if (s) {
QString format = s->toQString();
formattedTime = time.toString(format);
- } else if (ctx->args()[1].isNumber()) {
- quint32 intFormat = ctx->args()[1].asDouble();
+ } else if (callData->args[1].isNumber()) {
+ quint32 intFormat = callData->args[1].asDouble();
Qt::DateFormat format = Qt::DateFormat(intFormat);
formattedTime = time.toString(format);
} else {
- V4THROW_ERROR("Qt.formatTime(): Invalid time format");
+ THROW_GENERIC_ERROR("Qt.formatTime(): Invalid time format");
}
} else {
formattedTime = time.toString(enumFormat);
}
- return ctx->d()->engine->newString(formattedTime)->asReturnedValue();
+ scope.result = scope.engine->newString(formattedTime);
}
/*!
@@ -864,32 +879,31 @@ with the \a format values below to produce the following results:
\sa Locale
*/
-ReturnedValue QtObject::method_formatDateTime(QV4::CallContext *ctx)
+void QtObject::method_formatDateTime(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() < 1 || ctx->argc() > 2)
- V4THROW_ERROR("Qt.formatDateTime(): Invalid arguments");
- QV4::Scope scope(ctx);
+ if (callData->argc < 1 || callData->argc > 2)
+ THROW_GENERIC_ERROR("Qt.formatDateTime(): Invalid arguments");
Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate;
- QDateTime dt = ctx->engine()->toVariant(ctx->args()[0], -1).toDateTime();
+ QDateTime dt = scope.engine->toVariant(callData->args[0], -1).toDateTime();
QString formattedDt;
- if (ctx->argc() == 2) {
- QV4::ScopedString s(scope, ctx->args()[1]);
+ if (callData->argc == 2) {
+ QV4::ScopedString s(scope, callData->args[1]);
if (s) {
QString format = s->toQString();
formattedDt = dt.toString(format);
- } else if (ctx->args()[1].isNumber()) {
- quint32 intFormat = ctx->args()[1].asDouble();
+ } else if (callData->args[1].isNumber()) {
+ quint32 intFormat = callData->args[1].asDouble();
Qt::DateFormat format = Qt::DateFormat(intFormat);
formattedDt = dt.toString(format);
} else {
- V4THROW_ERROR("Qt.formatDateTime(): Invalid datetime format");
+ THROW_GENERIC_ERROR("Qt.formatDateTime(): Invalid datetime format");
}
} else {
formattedDt = dt.toString(enumFormat);
}
- return ctx->d()->engine->newString(formattedDt)->asReturnedValue();
+ scope.result = scope.engine->newString(formattedDt);
}
/*!
@@ -903,90 +917,94 @@ ReturnedValue QtObject::method_formatDateTime(QV4::CallContext *ctx)
still fail to launch or fail to open the requested URL. This result will not be reported back
to the application.
*/
-ReturnedValue QtObject::method_openUrlExternally(QV4::CallContext *ctx)
+void QtObject::method_openUrlExternally(const BuiltinFunction *b, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 1)
- return QV4::Encode(false);
+ if (callData->argc != 1) {
+ scope.result = QV4::Encode(false);
+ return;
+ }
- QUrl url(Value::fromReturnedValue(method_resolvedUrl(ctx)).toQStringNoThrow());
- return ctx->engine()->fromVariant(QQml_guiProvider()->openUrlExternally(url));
+ method_resolvedUrl(b, scope, callData);
+ QUrl url(scope.result.toQStringNoThrow());
+ scope.result = scope.engine->fromVariant(QQml_guiProvider()->openUrlExternally(url));
}
/*!
\qmlmethod url Qt::resolvedUrl(url url)
Returns \a url resolved relative to the URL of the caller.
*/
-ReturnedValue QtObject::method_resolvedUrl(QV4::CallContext *ctx)
+void QtObject::method_resolvedUrl(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- ExecutionEngine *v4 = ctx->engine();
+ ExecutionEngine *v4 = scope.engine;
- QUrl url = v4->toVariant(ctx->args()[0], -1).toUrl();
+ QUrl url = v4->toVariant(callData->args[0], -1).toUrl();
QQmlEngine *e = v4->qmlEngine();
QQmlEnginePrivate *p = 0;
if (e) p = QQmlEnginePrivate::get(e);
if (p) {
QQmlContextData *ctxt = v4->callingQmlContext();
if (ctxt)
- return v4->newString(ctxt->resolvedUrl(url).toString())->asReturnedValue();
+ scope.result = v4->newString(ctxt->resolvedUrl(url).toString());
else
- return v4->newString(url.toString())->asReturnedValue();
+ scope.result = v4->newString(url.toString());
+ return;
}
- return v4->newString(e->baseUrl().resolved(url).toString())->asReturnedValue();
+ scope.result = v4->newString(e->baseUrl().resolved(url).toString());
}
/*!
\qmlmethod list<string> Qt::fontFamilies()
Returns a list of the font families available to the application.
*/
-ReturnedValue QtObject::method_fontFamilies(CallContext *ctx)
+void QtObject::method_fontFamilies(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 0)
- V4THROW_ERROR("Qt.fontFamilies(): Invalid arguments");
+ if (callData->argc != 0)
+ THROW_GENERIC_ERROR("Qt.fontFamilies(): Invalid arguments");
- return ctx->engine()->fromVariant(QVariant(QQml_guiProvider()->fontFamilies()));
+ scope.result = scope.engine->fromVariant(QVariant(QQml_guiProvider()->fontFamilies()));
}
/*!
\qmlmethod string Qt::md5(data)
Returns a hex string of the md5 hash of \c data.
*/
-ReturnedValue QtObject::method_md5(CallContext *ctx)
+void QtObject::method_md5(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 1)
- V4THROW_ERROR("Qt.md5(): Invalid arguments");
+ if (callData->argc != 1)
+ THROW_GENERIC_ERROR("Qt.md5(): Invalid arguments");
- QByteArray data = ctx->args()[0].toQStringNoThrow().toUtf8();
+ QByteArray data = callData->args[0].toQStringNoThrow().toUtf8();
QByteArray result = QCryptographicHash::hash(data, QCryptographicHash::Md5);
- return ctx->d()->engine->newString(QLatin1String(result.toHex()))->asReturnedValue();
+ scope.result = scope.engine->newString(QLatin1String(result.toHex()));
}
/*!
\qmlmethod string Qt::btoa(data)
Binary to ASCII - this function returns a base64 encoding of \c data.
*/
-ReturnedValue QtObject::method_btoa(CallContext *ctx)
+void QtObject::method_btoa(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 1)
- V4THROW_ERROR("Qt.btoa(): Invalid arguments");
+ if (callData->argc != 1)
+ THROW_GENERIC_ERROR("Qt.btoa(): Invalid arguments");
- QByteArray data = ctx->args()[0].toQStringNoThrow().toUtf8();
+ QByteArray data = callData->args[0].toQStringNoThrow().toUtf8();
- return ctx->d()->engine->newString(QLatin1String(data.toBase64()))->asReturnedValue();
+ scope.result = scope.engine->newString(QLatin1String(data.toBase64()));
}
/*!
\qmlmethod string Qt::atob(data)
ASCII to binary - this function decodes the base64 encoded \a data string and returns it.
*/
-ReturnedValue QtObject::method_atob(CallContext *ctx)
+void QtObject::method_atob(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 1)
- V4THROW_ERROR("Qt.atob(): Invalid arguments");
+ if (callData->argc != 1)
+ THROW_GENERIC_ERROR("Qt.atob(): Invalid arguments");
- QByteArray data = ctx->args()[0].toQStringNoThrow().toLatin1();
+ QByteArray data = callData->args[0].toQStringNoThrow().toLatin1();
- return ctx->d()->engine->newString(QString::fromUtf8(QByteArray::fromBase64(data)))->asReturnedValue();
+ scope.result = scope.engine->newString(QString::fromUtf8(QByteArray::fromBase64(data)));
}
/*!
@@ -998,10 +1016,10 @@ QQmlEngine::quit() signal to the QCoreApplication::quit() slot.
\sa exit()
*/
-ReturnedValue QtObject::method_quit(CallContext *ctx)
+void QtObject::method_quit(const BuiltinFunction *, Scope &scope, CallData *)
{
- QQmlEnginePrivate::get(ctx->engine()->qmlEngine())->sendQuit();
- return QV4::Encode::undefined();
+ QQmlEnginePrivate::get(scope.engine->qmlEngine())->sendQuit();
+ scope.result = Encode::undefined();
}
/*!
@@ -1015,15 +1033,15 @@ ReturnedValue QtObject::method_quit(CallContext *ctx)
\sa quit()
*/
-ReturnedValue QtObject::method_exit(CallContext *ctx)
+void QtObject::method_exit(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 1)
- V4THROW_ERROR("Qt.exit(): Invalid arguments");
+ if (callData->argc != 1)
+ THROW_GENERIC_ERROR("Qt.exit(): Invalid arguments");
- int retCode = ctx->args()[0].toNumber();
+ int retCode = callData->args[0].toNumber();
- QQmlEnginePrivate::get(ctx->engine()->qmlEngine())->sendExit(retCode);
- return QV4::Encode::undefined();
+ QQmlEnginePrivate::get(scope.engine->qmlEngine())->sendExit(retCode);
+ scope.result = QV4::Encode::undefined();
}
/*!
@@ -1050,11 +1068,10 @@ If this is the case, consider using \l{QtQml::Qt::createComponent()}{Qt.createCo
See \l {Dynamic QML Object Creation from JavaScript} for more information on using this function.
*/
-ReturnedValue QtObject::method_createQmlObject(CallContext *ctx)
+void QtObject::method_createQmlObject(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- Scope scope(ctx);
- if (ctx->argc() < 2 || ctx->argc() > 3)
- V4THROW_ERROR("Qt.createQmlObject(): Invalid arguments");
+ if (callData->argc < 2 || callData->argc > 3)
+ THROW_GENERIC_ERROR("Qt.createQmlObject(): Invalid arguments");
struct Error {
static ReturnedValue create(QV4::ExecutionEngine *v4, const QList<QQmlError> &errors) {
@@ -1085,7 +1102,7 @@ ReturnedValue QtObject::method_createQmlObject(CallContext *ctx)
}
};
- QV8Engine *v8engine = ctx->d()->engine->v8Engine;
+ QV8Engine *v8engine = scope.engine->v8Engine;
QQmlEngine *engine = v8engine->engine();
QQmlContextData *context = scope.engine->callingQmlContext();
@@ -1097,13 +1114,13 @@ ReturnedValue QtObject::method_createQmlObject(CallContext *ctx)
effectiveContext = context->asQQmlContext();
Q_ASSERT(effectiveContext);
- QString qml = ctx->args()[0].toQStringNoThrow();
+ QString qml = callData->args[0].toQStringNoThrow();
if (qml.isEmpty())
- return QV4::Encode::null();
+ RETURN_RESULT(Encode::null());
QUrl url;
- if (ctx->argc() > 2)
- url = QUrl(ctx->args()[2].toQStringNoThrow());
+ if (callData->argc > 2)
+ url = QUrl(callData->args[2].toQStringNoThrow());
else
url = QUrl(QLatin1String("inline"));
@@ -1111,11 +1128,11 @@ ReturnedValue QtObject::method_createQmlObject(CallContext *ctx)
url = context->resolvedUrl(url);
QObject *parentArg = 0;
- QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, ctx->args()[1]);
+ QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, callData->args[1]);
if (!!qobjectWrapper)
parentArg = qobjectWrapper->object();
if (!parentArg)
- V4THROW_ERROR("Qt.createQmlObject(): Missing parent object");
+ THROW_GENERIC_ERROR("Qt.createQmlObject(): Missing parent object");
QQmlTypeData *typeData = QQmlEnginePrivate::get(engine)->typeLoader.getType(
qml.toUtf8(), url, QQmlTypeLoader::Synchronous);
@@ -1126,12 +1143,12 @@ ReturnedValue QtObject::method_createQmlObject(CallContext *ctx)
componentPrivate->progress = 1.0;
if (component.isError()) {
- ScopedValue v(scope, Error::create(ctx->d()->engine, component.errors()));
- return ctx->engine()->throwError(v);
+ ScopedValue v(scope, Error::create(scope.engine, component.errors()));
+ RETURN_RESULT(scope.engine->throwError(v));
}
if (!component.isReady())
- V4THROW_ERROR("Qt.createQmlObject(): Component is not ready");
+ THROW_GENERIC_ERROR("Qt.createQmlObject(): Component is not ready");
QObject *obj = component.beginCreate(effectiveContext);
if (obj) {
@@ -1150,13 +1167,14 @@ ReturnedValue QtObject::method_createQmlObject(CallContext *ctx)
component.completeCreate();
if (component.isError()) {
- ScopedValue v(scope, Error::create(ctx->d()->engine, component.errors()));
- return ctx->engine()->throwError(v);
+ ScopedValue v(scope, Error::create(scope.engine, component.errors()));
+ scope.result = scope.engine->throwError(v);
+ return;
}
Q_ASSERT(obj);
- return QV4::QObjectWrapper::wrap(ctx->d()->engine, obj);
+ scope.result = QV4::QObjectWrapper::wrap(scope.engine, obj);
}
/*!
@@ -1203,14 +1221,12 @@ See \l {Dynamic QML Object Creation from JavaScript} for more information on usi
To create a QML object from an arbitrary string of QML (instead of a file),
use \l{QtQml::Qt::createQmlObject()}{Qt.createQmlObject()}.
*/
-ReturnedValue QtObject::method_createComponent(CallContext *ctx)
+void QtObject::method_createComponent(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() < 1 || ctx->argc() > 3)
- return ctx->engine()->throwError(QStringLiteral("Qt.createComponent(): Invalid arguments"));
+ if (callData->argc < 1 || callData->argc > 3)
+ THROW_GENERIC_ERROR("Qt.createComponent(): Invalid arguments");
- Scope scope(ctx);
-
- QV8Engine *v8engine = ctx->d()->engine->v8Engine;
+ QV8Engine *v8engine = scope.engine->v8Engine;
QQmlEngine *engine = v8engine->engine();
QQmlContextData *context = scope.engine->callingQmlContext();
@@ -1219,41 +1235,41 @@ ReturnedValue QtObject::method_createComponent(CallContext *ctx)
if (context->isPragmaLibraryContext)
effectiveContext = 0;
- QString arg = ctx->args()[0].toQStringNoThrow();
+ QString arg = callData->args[0].toQStringNoThrow();
if (arg.isEmpty())
- return QV4::Encode::null();
+ RETURN_RESULT(QV4::Encode::null());
QQmlComponent::CompilationMode compileMode = QQmlComponent::PreferSynchronous;
QObject *parentArg = 0;
int consumedCount = 1;
- if (ctx->argc() > 1) {
- ScopedValue lastArg(scope, ctx->args()[ctx->argc()-1]);
+ if (callData->argc > 1) {
+ ScopedValue lastArg(scope, callData->args[callData->argc-1]);
// The second argument could be the mode enum
- if (ctx->args()[1].isInteger()) {
- int mode = ctx->args()[1].integerValue();
+ if (callData->args[1].isInteger()) {
+ int mode = callData->args[1].integerValue();
if (mode != int(QQmlComponent::PreferSynchronous) && mode != int(QQmlComponent::Asynchronous))
- return ctx->engine()->throwError(QStringLiteral("Qt.createComponent(): Invalid arguments"));
+ THROW_GENERIC_ERROR("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->argc() != 2) || !(lastArg->isObject() || lastArg->isNull()))
- return ctx->engine()->throwError(QStringLiteral("Qt.createComponent(): Invalid arguments"));
+ if ((callData->argc != 2) || !(lastArg->isObject() || lastArg->isNull()))
+ THROW_GENERIC_ERROR("Qt.createComponent(): Invalid arguments");
}
- if (consumedCount < ctx->argc()) {
+ if (consumedCount < callData->argc) {
if (lastArg->isObject()) {
Scoped<QObjectWrapper> qobjectWrapper(scope, lastArg);
if (qobjectWrapper)
parentArg = qobjectWrapper->object();
if (!parentArg)
- return ctx->engine()->throwError(QStringLiteral("Qt.createComponent(): Invalid parent object"));
+ THROW_GENERIC_ERROR("Qt.createComponent(): Invalid parent object");
} else if (lastArg->isNull()) {
parentArg = 0;
} else {
- return ctx->engine()->throwError(QStringLiteral("Qt.createComponent(): Invalid parent object"));
+ THROW_GENERIC_ERROR("Qt.createComponent(): Invalid parent object");
}
}
}
@@ -1264,7 +1280,7 @@ ReturnedValue QtObject::method_createComponent(CallContext *ctx)
QQmlData::get(c, true)->explicitIndestructibleSet = false;
QQmlData::get(c)->indestructible = false;
- return QV4::QObjectWrapper::wrap(ctx->d()->engine, c);
+ scope.result = QV4::QObjectWrapper::wrap(scope.engine, c);
}
/*!
@@ -1287,18 +1303,18 @@ ReturnedValue QtObject::method_createComponent(CallContext *ctx)
\sa Locale
*/
-ReturnedValue QtObject::method_locale(CallContext *ctx)
+void QtObject::method_locale(const BuiltinFunction *, Scope &scope, CallData *callData)
{
QString code;
- if (ctx->argc() > 1)
- V4THROW_ERROR("locale() requires 0 or 1 argument");
- if (ctx->argc() == 1 && !ctx->args()[0].isString())
- V4THROW_TYPE("locale(): argument (locale code) must be a string");
+ if (callData->argc > 1)
+ THROW_GENERIC_ERROR("locale() requires 0 or 1 argument");
+ if (callData->argc == 1 && !callData->args[0].isString())
+ THROW_TYPE_ERROR_WITH_MESSAGE("locale(): argument (locale code) must be a string");
- if (ctx->argc() == 1)
- code = ctx->args()[0].toQStringNoThrow();
+ if (callData->argc == 1)
+ code = callData->args[0].toQStringNoThrow();
- return QQmlLocale::locale(ctx->engine(), code);
+ scope.result = QQmlLocale::locale(scope.engine, code);
}
void Heap::QQmlBindingFunction::init(const QV4::FunctionObject *originalFunction)
@@ -1360,62 +1376,62 @@ DEFINE_OBJECT_VTABLE(QQmlBindingFunction);
\since 5.0
*/
-ReturnedValue QtObject::method_binding(CallContext *ctx)
+void QtObject::method_binding(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 1)
- V4THROW_ERROR("binding() requires 1 argument");
- const QV4::FunctionObject *f = ctx->args()[0].as<FunctionObject>();
+ if (callData->argc != 1)
+ THROW_GENERIC_ERROR("binding() requires 1 argument");
+ const QV4::FunctionObject *f = callData->args[0].as<FunctionObject>();
if (!f)
- V4THROW_TYPE("binding(): argument (binding expression) must be a function");
+ THROW_TYPE_ERROR_WITH_MESSAGE("binding(): argument (binding expression) must be a function");
- return (ctx->d()->engine->memoryManager->allocObject<QQmlBindingFunction>(f))->asReturnedValue();
+ scope.result = scope.engine->memoryManager->allocObject<QQmlBindingFunction>(f);
}
-ReturnedValue QtObject::method_get_platform(CallContext *ctx)
+void QtObject::method_get_platform(const BuiltinFunction *, Scope &scope, CallData *callData)
{
// ### inefficient. Should be just a value based getter
- Object *o = ctx->thisObject().as<Object>();
+ Object *o = callData->thisObject.as<Object>();
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
QtObject *qt = o->as<QtObject>();
if (!qt)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
if (!qt->d()->platform)
// Only allocate a platform object once
- qt->d()->platform = new QQmlPlatform(ctx->d()->engine->jsEngine());
+ qt->d()->platform = new QQmlPlatform(scope.engine->jsEngine());
- return QV4::QObjectWrapper::wrap(ctx->d()->engine, qt->d()->platform);
+ scope.result = QV4::QObjectWrapper::wrap(scope.engine, qt->d()->platform);
}
-ReturnedValue QtObject::method_get_application(CallContext *ctx)
+void QtObject::method_get_application(const BuiltinFunction *, Scope &scope, CallData *callData)
{
// ### inefficient. Should be just a value based getter
- Object *o = ctx->thisObject().as<Object>();
+ Object *o = callData->thisObject.as<Object>();
if (!o)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
QtObject *qt = o->as<QtObject>();
if (!qt)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
if (!qt->d()->application)
// Only allocate an application object once
- qt->d()->application = QQml_guiProvider()->application(ctx->d()->engine->jsEngine());
+ qt->d()->application = QQml_guiProvider()->application(scope.engine->jsEngine());
- return QV4::QObjectWrapper::wrap(ctx->d()->engine, qt->d()->application);
+ scope.result = QV4::QObjectWrapper::wrap(scope.engine, qt->d()->application);
}
-ReturnedValue QtObject::method_get_inputMethod(CallContext *ctx)
+void QtObject::method_get_inputMethod(const BuiltinFunction *, Scope &scope, CallData *)
{
QObject *o = QQml_guiProvider()->inputMethod();
- return QV4::QObjectWrapper::wrap(ctx->d()->engine, o);
+ scope.result = QV4::QObjectWrapper::wrap(scope.engine, o);
}
-ReturnedValue QtObject::method_get_styleHints(CallContext *ctx)
+void QtObject::method_get_styleHints(const BuiltinFunction *, Scope &scope, CallData *)
{
QObject *o = QQml_guiProvider()->styleHints();
- return QV4::QObjectWrapper::wrap(ctx->d()->engine, o);
+ scope.result = QV4::QObjectWrapper::wrap(scope.engine, o);
}
@@ -1475,35 +1491,35 @@ static QString jsStack(QV4::ExecutionEngine *engine) {
return stack;
}
-static QV4::ReturnedValue writeToConsole(ConsoleLogTypes logType, CallContext *ctx,
- bool printStack = false)
+static void writeToConsole(const BuiltinFunction *, Scope &scope, CallData *callData,
+ ConsoleLogTypes logType, bool printStack = false)
{
QLoggingCategory *loggingCategory = 0;
QString result;
- QV4::ExecutionEngine *v4 = ctx->d()->engine;
+ QV4::ExecutionEngine *v4 = scope.engine;
int start = 0;
- if (ctx->argc() > 0) {
- if (const QObjectWrapper* wrapper = ctx->args()[0].as<QObjectWrapper>()) {
+ if (callData->argc > 0) {
+ if (const QObjectWrapper* wrapper = callData->args[0].as<QObjectWrapper>()) {
if (QQmlLoggingCategory* category = qobject_cast<QQmlLoggingCategory*>(wrapper->object())) {
if (category->category())
loggingCategory = category->category();
else
- V4THROW_ERROR("A QmlLoggingCatgory was provided without a valid name");
+ THROW_GENERIC_ERROR("A QmlLoggingCatgory was provided without a valid name");
start = 1;
}
}
}
- for (int i = start; i < ctx->argc(); ++i) {
+ for (int i = start; i < callData->argc; ++i) {
if (i != start)
result.append(QLatin1Char(' '));
- if (ctx->args()[i].as<ArrayObject>())
- result += QLatin1Char('[') + ctx->args()[i].toQStringNoThrow() + QLatin1Char(']');
+ if (callData->args[i].as<ArrayObject>())
+ result += QLatin1Char('[') + callData->args[i].toQStringNoThrow() + QLatin1Char(']');
else
- result.append(ctx->args()[i].toQStringNoThrow());
+ result.append(callData->args[i].toQStringNoThrow());
}
if (printStack)
@@ -1540,32 +1556,32 @@ static QV4::ReturnedValue writeToConsole(ConsoleLogTypes logType, CallContext *c
break;
}
- return QV4::Encode::undefined();
+ scope.result = QV4::Encode::undefined();
}
DEFINE_OBJECT_VTABLE(ConsoleObject);
-QV4::ReturnedValue ConsoleObject::method_error(CallContext *ctx)
+void ConsoleObject::method_error(const BuiltinFunction *b, Scope &scope, CallData *callData)
{
- return writeToConsole(Error, ctx);
+ writeToConsole(b, scope, callData, Error);
}
-QV4::ReturnedValue ConsoleObject::method_log(CallContext *ctx)
+void ConsoleObject::method_log(const BuiltinFunction *b, Scope &scope, CallData *callData)
{
//console.log
//console.debug
//print
- return writeToConsole(Log, ctx);
+ writeToConsole(b, scope, callData, Log);
}
-QV4::ReturnedValue ConsoleObject::method_info(CallContext *ctx)
+void ConsoleObject::method_info(const BuiltinFunction *b, Scope &scope, CallData *callData)
{
- return writeToConsole(Info, ctx);
+ writeToConsole(b, scope, callData, Info);
}
-QV4::ReturnedValue ConsoleObject::method_profile(CallContext *ctx)
+void ConsoleObject::method_profile(const BuiltinFunction *, Scope &scope, CallData *)
{
- QV4::ExecutionEngine *v4 = ctx->d()->engine;
+ QV4::ExecutionEngine *v4 = scope.engine;
QV4::StackFrame frame = v4->currentStackFrame();
const QByteArray baSource = frame.source.toUtf8();
@@ -1579,12 +1595,12 @@ QV4::ReturnedValue ConsoleObject::method_profile(CallContext *ctx)
logger.debug("Profiling started.");
}
- return QV4::Encode::undefined();
+ scope.result = QV4::Encode::undefined();
}
-QV4::ReturnedValue ConsoleObject::method_profileEnd(CallContext *ctx)
+void ConsoleObject::method_profileEnd(const BuiltinFunction *, Scope &scope, CallData *)
{
- QV4::ExecutionEngine *v4 = ctx->d()->engine;
+ QV4::ExecutionEngine *v4 = scope.engine;
QV4::StackFrame frame = v4->currentStackFrame();
const QByteArray baSource = frame.source.toUtf8();
@@ -1599,46 +1615,46 @@ QV4::ReturnedValue ConsoleObject::method_profileEnd(CallContext *ctx)
logger.debug("Profiling ended.");
}
- return QV4::Encode::undefined();
+ scope.result = QV4::Encode::undefined();
}
-QV4::ReturnedValue ConsoleObject::method_time(CallContext *ctx)
+void ConsoleObject::method_time(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 1)
- V4THROW_ERROR("console.time(): Invalid arguments");
+ if (callData->argc != 1)
+ THROW_GENERIC_ERROR("console.time(): Invalid arguments");
- QV8Engine *v8engine = ctx->d()->engine->v8Engine;
+ QV8Engine *v8engine = scope.engine->v8Engine;
- QString name = ctx->args()[0].toQStringNoThrow();
+ QString name = callData->args[0].toQStringNoThrow();
v8engine->startTimer(name);
- return QV4::Encode::undefined();
+ scope.result = QV4::Encode::undefined();
}
-QV4::ReturnedValue ConsoleObject::method_timeEnd(CallContext *ctx)
+void ConsoleObject::method_timeEnd(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 1)
- V4THROW_ERROR("console.timeEnd(): Invalid arguments");
+ if (callData->argc != 1)
+ THROW_GENERIC_ERROR("console.timeEnd(): Invalid arguments");
- QV8Engine *v8engine = ctx->d()->engine->v8Engine;
+ QV8Engine *v8engine = scope.engine->v8Engine;
- QString name = ctx->args()[0].toQStringNoThrow();
+ QString name = callData->args[0].toQStringNoThrow();
bool wasRunning;
qint64 elapsed = v8engine->stopTimer(name, &wasRunning);
if (wasRunning) {
qDebug("%s: %llims", qPrintable(name), elapsed);
}
- return QV4::Encode::undefined();
+ scope.result = QV4::Encode::undefined();
}
-QV4::ReturnedValue ConsoleObject::method_count(CallContext *ctx)
+void ConsoleObject::method_count(const BuiltinFunction *, Scope &scope, CallData *callData)
{
// first argument: name to print. Ignore any additional arguments
QString name;
- if (ctx->argc() > 0)
- name = ctx->args()[0].toQStringNoThrow();
+ if (callData->argc > 0)
+ name = callData->args[0].toQStringNoThrow();
- QV4::ExecutionEngine *v4 = ctx->d()->engine;
- QV8Engine *v8engine = ctx->d()->engine->v8Engine;
+ QV4::ExecutionEngine *v4 = scope.engine;
+ QV8Engine *v8engine = scope.engine->v8Engine;
QV4::StackFrame frame = v4->currentStackFrame();
@@ -1651,15 +1667,15 @@ QV4::ReturnedValue ConsoleObject::method_count(CallContext *ctx)
qPrintable(frame.function))
.debug("%s", qPrintable(message));
- return QV4::Encode::undefined();
+ scope.result = QV4::Encode::undefined();
}
-QV4::ReturnedValue ConsoleObject::method_trace(CallContext *ctx)
+void ConsoleObject::method_trace(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 0)
- V4THROW_ERROR("console.trace(): Invalid arguments");
+ if (callData->argc != 0)
+ THROW_GENERIC_ERROR("console.trace(): Invalid arguments");
- QV4::ExecutionEngine *v4 = ctx->d()->engine;
+ QV4::ExecutionEngine *v4 = scope.engine;
QString stack = jsStack(v4);
@@ -1668,28 +1684,28 @@ QV4::ReturnedValue ConsoleObject::method_trace(CallContext *ctx)
frame.function.toUtf8().constData())
.debug("%s", qPrintable(stack));
- return QV4::Encode::undefined();
+ scope.result = QV4::Encode::undefined();
}
-QV4::ReturnedValue ConsoleObject::method_warn(CallContext *ctx)
+void ConsoleObject::method_warn(const BuiltinFunction *b, Scope &scope, CallData *callData)
{
- return writeToConsole(Warn, ctx);
+ return writeToConsole(b, scope, callData, Warn);
}
-QV4::ReturnedValue ConsoleObject::method_assert(CallContext *ctx)
+void ConsoleObject::method_assert(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() == 0)
- V4THROW_ERROR("console.assert(): Missing argument");
+ if (callData->argc == 0)
+ THROW_GENERIC_ERROR("console.assert(): Missing argument");
- QV4::ExecutionEngine *v4 = ctx->d()->engine;
+ QV4::ExecutionEngine *v4 = scope.engine;
- if (!ctx->args()[0].toBoolean()) {
+ if (!callData->args[0].toBoolean()) {
QString message;
- for (int i = 1; i < ctx->argc(); ++i) {
+ for (int i = 1; i < callData->argc; ++i) {
if (i != 1)
message.append(QLatin1Char(' '));
- message.append(ctx->args()[i].toQStringNoThrow());
+ message.append(callData->args[i].toQStringNoThrow());
}
QString stack = jsStack(v4);
@@ -1700,17 +1716,17 @@ QV4::ReturnedValue ConsoleObject::method_assert(CallContext *ctx)
.critical("%s\n%s",qPrintable(message), qPrintable(stack));
}
- return QV4::Encode::undefined();
+ scope.result = QV4::Encode::undefined();
}
-QV4::ReturnedValue ConsoleObject::method_exception(CallContext *ctx)
+void ConsoleObject::method_exception(const BuiltinFunction *b, Scope &scope, CallData *callData)
{
- if (ctx->argc() == 0)
- V4THROW_ERROR("console.exception(): Missing argument");
+ if (callData->argc == 0)
+ THROW_GENERIC_ERROR("console.exception(): Missing argument");
- writeToConsole(Error, ctx, true);
+ writeToConsole(b, scope, callData, Error, true);
- return QV4::Encode::undefined();
+ scope.result = QV4::Encode::undefined();
}
@@ -1766,38 +1782,38 @@ void QV4::GlobalExtensions::init(Object *globalObject, QJSEngine::Extensions ext
\sa {Internationalization and Localization with Qt Quick}
*/
-ReturnedValue GlobalExtensions::method_qsTranslate(CallContext *ctx)
-{
- if (ctx->argc() < 2)
- V4THROW_ERROR("qsTranslate() requires at least two arguments");
- if (!ctx->args()[0].isString())
- V4THROW_ERROR("qsTranslate(): first argument (context) must be a string");
- if (!ctx->args()[1].isString())
- V4THROW_ERROR("qsTranslate(): second argument (sourceText) must be a string");
- if ((ctx->argc() > 2) && !ctx->args()[2].isString())
- V4THROW_ERROR("qsTranslate(): third argument (disambiguation) must be a string");
-
- QString context = ctx->args()[0].toQStringNoThrow();
- QString text = ctx->args()[1].toQStringNoThrow();
+void GlobalExtensions::method_qsTranslate(const BuiltinFunction *, Scope &scope, CallData *callData)
+{
+ if (callData->argc < 2)
+ THROW_GENERIC_ERROR("qsTranslate() requires at least two arguments");
+ if (!callData->args[0].isString())
+ THROW_GENERIC_ERROR("qsTranslate(): first argument (context) must be a string");
+ if (!callData->args[1].isString())
+ THROW_GENERIC_ERROR("qsTranslate(): second argument (sourceText) must be a string");
+ if ((callData->argc > 2) && !callData->args[2].isString())
+ THROW_GENERIC_ERROR("qsTranslate(): third argument (disambiguation) must be a string");
+
+ QString context = callData->args[0].toQStringNoThrow();
+ QString text = callData->args[1].toQStringNoThrow();
QString comment;
- if (ctx->argc() > 2) comment = ctx->args()[2].toQStringNoThrow();
+ if (callData->argc > 2) comment = callData->args[2].toQStringNoThrow();
int i = 3;
- if (ctx->argc() > i && ctx->args()[i].isString()) {
+ if (callData->argc > i && callData->args[i].isString()) {
qWarning("qsTranslate(): specifying the encoding as fourth argument is deprecated");
++i;
}
int n = -1;
- if (ctx->argc() > i)
- n = ctx->args()[i].toInt32();
+ if (callData->argc > i)
+ n = callData->args[i].toInt32();
QString result = QCoreApplication::translate(context.toUtf8().constData(),
text.toUtf8().constData(),
comment.toUtf8().constData(),
n);
- return ctx->d()->engine->newString(result)->asReturnedValue();
+ scope.result = scope.engine->newString(result);
}
/*!
@@ -1822,11 +1838,12 @@ ReturnedValue GlobalExtensions::method_qsTranslate(CallContext *ctx)
\sa {Internationalization and Localization with Qt Quick}
*/
-ReturnedValue GlobalExtensions::method_qsTranslateNoOp(CallContext *ctx)
+void GlobalExtensions::method_qsTranslateNoOp(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() < 2)
- return QV4::Encode::undefined();
- return ctx->args()[1].asReturnedValue();
+ if (callData->argc < 2)
+ scope.result = QV4::Encode::undefined();
+ else
+ scope.result = callData->args[1];
}
/*!
@@ -1846,18 +1863,17 @@ ReturnedValue GlobalExtensions::method_qsTranslateNoOp(CallContext *ctx)
\sa {Internationalization and Localization with Qt Quick}
*/
-ReturnedValue GlobalExtensions::method_qsTr(CallContext *ctx)
-{
- if (ctx->argc() < 1)
- V4THROW_ERROR("qsTr() requires at least one argument");
- if (!ctx->args()[0].isString())
- V4THROW_ERROR("qsTr(): first argument (sourceText) must be a string");
- if ((ctx->argc() > 1) && !ctx->args()[1].isString())
- V4THROW_ERROR("qsTr(): second argument (disambiguation) must be a string");
- if ((ctx->argc() > 2) && !ctx->args()[2].isNumber())
- V4THROW_ERROR("qsTr(): third argument (n) must be a number");
-
- Scope scope(ctx);
+void GlobalExtensions::method_qsTr(const BuiltinFunction *, Scope &scope, CallData *callData)
+{
+ if (callData->argc < 1)
+ THROW_GENERIC_ERROR("qsTr() requires at least one argument");
+ if (!callData->args[0].isString())
+ THROW_GENERIC_ERROR("qsTr(): first argument (sourceText) must be a string");
+ if ((callData->argc > 1) && !callData->args[1].isString())
+ THROW_GENERIC_ERROR("qsTr(): second argument (disambiguation) must be a string");
+ if ((callData->argc > 2) && !callData->args[2].isNumber())
+ THROW_GENERIC_ERROR("qsTr(): third argument (n) must be a number");
+
QString context;
if (QQmlContextData *ctxt = scope.engine->callingQmlContext()) {
QString path = ctxt->urlString();
@@ -1866,7 +1882,7 @@ ReturnedValue GlobalExtensions::method_qsTr(CallContext *ctx)
int length = lastDot - (lastSlash + 1);
context = (lastSlash > -1) ? path.mid(lastSlash + 1, (length > -1) ? length : -1) : QString();
} else {
- ExecutionContext *parentCtx = scope.engine->parentContext(ctx);
+ ExecutionContext *parentCtx = scope.engine->currentContext;
// The first non-empty source URL in the call stack determines the translation context.
while (!!parentCtx && context.isEmpty()) {
if (QV4::CompiledData::CompilationUnit *unit = parentCtx->d()->compilationUnit) {
@@ -1885,18 +1901,18 @@ ReturnedValue GlobalExtensions::method_qsTr(CallContext *ctx)
}
}
- QString text = ctx->args()[0].toQStringNoThrow();
+ QString text = callData->args[0].toQStringNoThrow();
QString comment;
- if (ctx->argc() > 1)
- comment = ctx->args()[1].toQStringNoThrow();
+ if (callData->argc > 1)
+ comment = callData->args[1].toQStringNoThrow();
int n = -1;
- if (ctx->argc() > 2)
- n = ctx->args()[2].toInt32();
+ if (callData->argc > 2)
+ n = callData->args[2].toInt32();
QString result = QCoreApplication::translate(context.toUtf8().constData(), text.toUtf8().constData(),
comment.toUtf8().constData(), n);
- return ctx->d()->engine->newString(result)->asReturnedValue();
+ scope.result = scope.engine->newString(result);
}
/*!
@@ -1921,11 +1937,12 @@ ReturnedValue GlobalExtensions::method_qsTr(CallContext *ctx)
\sa {Internationalization and Localization with Qt Quick}
*/
-ReturnedValue GlobalExtensions::method_qsTrNoOp(CallContext *ctx)
+void GlobalExtensions::method_qsTrNoOp(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() < 1)
- return QV4::Encode::undefined();
- return ctx->args()[0].asReturnedValue();
+ if (callData->argc < 1)
+ scope.result = QV4::Encode::undefined();
+ else
+ scope.result = callData->args[0];
}
/*!
@@ -1958,20 +1975,20 @@ ReturnedValue GlobalExtensions::method_qsTrNoOp(CallContext *ctx)
\sa QT_TRID_NOOP(), {Internationalization and Localization with Qt Quick}
*/
-ReturnedValue GlobalExtensions::method_qsTrId(CallContext *ctx)
+void GlobalExtensions::method_qsTrId(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() < 1)
- V4THROW_ERROR("qsTrId() requires at least one argument");
- if (!ctx->args()[0].isString())
- V4THROW_TYPE("qsTrId(): first argument (id) must be a string");
- if (ctx->argc() > 1 && !ctx->args()[1].isNumber())
- V4THROW_TYPE("qsTrId(): second argument (n) must be a number");
+ if (callData->argc < 1)
+ THROW_GENERIC_ERROR("qsTrId() requires at least one argument");
+ if (!callData->args[0].isString())
+ THROW_TYPE_ERROR_WITH_MESSAGE("qsTrId(): first argument (id) must be a string");
+ if (callData->argc > 1 && !callData->args[1].isNumber())
+ THROW_TYPE_ERROR_WITH_MESSAGE("qsTrId(): second argument (n) must be a number");
int n = -1;
- if (ctx->argc() > 1)
- n = ctx->args()[1].toInt32();
+ if (callData->argc > 1)
+ n = callData->args[1].toInt32();
- return ctx->d()->engine->newString(qtTrId(ctx->args()[0].toQStringNoThrow().toUtf8().constData(), n))->asReturnedValue();
+ scope.result = scope.engine->newString(qtTrId(callData->args[0].toQStringNoThrow().toUtf8().constData(), n));
}
/*!
@@ -1990,41 +2007,41 @@ ReturnedValue GlobalExtensions::method_qsTrId(CallContext *ctx)
\sa qsTrId(), {Internationalization and Localization with Qt Quick}
*/
-ReturnedValue GlobalExtensions::method_qsTrIdNoOp(CallContext *ctx)
+void GlobalExtensions::method_qsTrIdNoOp(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() < 1)
- return QV4::Encode::undefined();
- return ctx->args()[0].asReturnedValue();
+ if (callData->argc < 1)
+ scope.result = QV4::Encode::undefined();
+ else
+ scope.result = callData->args[0];
}
#endif // translation
-QV4::ReturnedValue GlobalExtensions::method_gc(CallContext *ctx)
+void GlobalExtensions::method_gc(const BuiltinFunction *, Scope &scope, CallData *)
{
- ctx->d()->engine->memoryManager->runGC();
+ scope.engine->memoryManager->runGC();
- return QV4::Encode::undefined();
+ scope.result = QV4::Encode::undefined();
}
-ReturnedValue GlobalExtensions::method_string_arg(CallContext *ctx)
+void GlobalExtensions::method_string_arg(const BuiltinFunction *, Scope &scope, CallData *callData)
{
- if (ctx->argc() != 1)
- V4THROW_ERROR("String.arg(): Invalid arguments");
+ if (callData->argc != 1)
+ THROW_GENERIC_ERROR("String.arg(): Invalid arguments");
- QString value = ctx->thisObject().toQString();
+ QString value = callData->thisObject.toQString();
- QV4::Scope scope(ctx);
- QV4::ScopedValue arg(scope, ctx->args()[0]);
+ QV4::ScopedValue arg(scope, callData->args[0]);
if (arg->isInteger())
- return ctx->d()->engine->newString(value.arg(arg->integerValue()))->asReturnedValue();
+ RETURN_RESULT(scope.engine->newString(value.arg(arg->integerValue())));
else if (arg->isDouble())
- return ctx->d()->engine->newString(value.arg(arg->doubleValue()))->asReturnedValue();
+ RETURN_RESULT(scope.engine->newString(value.arg(arg->doubleValue())));
else if (arg->isBoolean())
- return ctx->d()->engine->newString(value.arg(arg->booleanValue()))->asReturnedValue();
+ RETURN_RESULT(scope.engine->newString(value.arg(arg->booleanValue())));
- return ctx->d()->engine->newString(value.arg(arg->toQString()))->asReturnedValue();
+ RETURN_RESULT(scope.engine->newString(value.arg(arg->toQString())));
}
/*!
@@ -2047,10 +2064,10 @@ be passed on to the function invoked. Note that if redundant calls
are eliminated, then only the last set of arguments will be passed to the
function.
*/
-ReturnedValue QtObject::method_callLater(CallContext *ctx)
+void QtObject::method_callLater(const BuiltinFunction *b, Scope &scope, CallData *callData)
{
- QV8Engine *v8engine = ctx->engine()->v8Engine;
- return v8engine->delayedCallQueue()->addUniquelyAndExecuteLater(ctx);
+ QV8Engine *v8engine = scope.engine->v8Engine;
+ v8engine->delayedCallQueue()->addUniquelyAndExecuteLater(b, scope, callData);
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
index fe43532647..21613b7c10 100644
--- a/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
+++ b/src/qml/qml/v8/qqmlbuiltinfunctions_p.h
@@ -93,45 +93,45 @@ struct QtObject : Object
static ReturnedValue get(const Managed *m, String *name, bool *hasProperty);
static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes);
- static ReturnedValue method_isQtObject(CallContext *ctx);
- static ReturnedValue method_rgba(CallContext *ctx);
- static ReturnedValue method_hsla(CallContext *ctx);
- static ReturnedValue method_hsva(CallContext *ctx);
- static ReturnedValue method_colorEqual(CallContext *ctx);
- static ReturnedValue method_font(CallContext *ctx);
- static ReturnedValue method_rect(CallContext *ctx);
- static ReturnedValue method_point(CallContext *ctx);
- static ReturnedValue method_size(CallContext *ctx);
- static ReturnedValue method_vector2d(CallContext *ctx);
- static ReturnedValue method_vector3d(CallContext *ctx);
- static ReturnedValue method_vector4d(CallContext *ctx);
- static ReturnedValue method_quaternion(CallContext *ctx);
- static ReturnedValue method_matrix4x4(CallContext *ctx);
- static ReturnedValue method_lighter(CallContext *ctx);
- static ReturnedValue method_darker(CallContext *ctx);
- static ReturnedValue method_tint(CallContext *ctx);
- static ReturnedValue method_formatDate(CallContext *ctx);
- static ReturnedValue method_formatTime(CallContext *ctx);
- static ReturnedValue method_formatDateTime(CallContext *ctx);
- static ReturnedValue method_openUrlExternally(CallContext *ctx);
- static ReturnedValue method_fontFamilies(CallContext *ctx);
- static ReturnedValue method_md5(CallContext *ctx);
- static ReturnedValue method_btoa(CallContext *ctx);
- static ReturnedValue method_atob(CallContext *ctx);
- static ReturnedValue method_quit(CallContext *ctx);
- static ReturnedValue method_exit(CallContext *ctx);
- static ReturnedValue method_resolvedUrl(CallContext *ctx);
- static ReturnedValue method_createQmlObject(CallContext *ctx);
- static ReturnedValue method_createComponent(CallContext *ctx);
- static ReturnedValue method_locale(CallContext *ctx);
- static ReturnedValue method_binding(CallContext *ctx);
-
- static ReturnedValue method_get_platform(CallContext *ctx);
- static ReturnedValue method_get_application(CallContext *ctx);
- static ReturnedValue method_get_inputMethod(CallContext *ctx);
- static ReturnedValue method_get_styleHints(CallContext *ctx);
-
- static ReturnedValue method_callLater(CallContext *ctx);
+ static void method_isQtObject(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_rgba(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_hsla(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_hsva(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_colorEqual(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_font(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_rect(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_point(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_size(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_vector2d(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_vector3d(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_vector4d(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_quaternion(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_matrix4x4(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_lighter(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_darker(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_tint(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_formatDate(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_formatTime(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_formatDateTime(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_openUrlExternally(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_fontFamilies(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_md5(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_btoa(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_atob(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_quit(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_exit(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_resolvedUrl(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_createQmlObject(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_createComponent(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_locale(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_binding(const BuiltinFunction *, Scope &scope, CallData *callData);
+
+ static void method_get_platform(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_get_application(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_get_inputMethod(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_get_styleHints(const BuiltinFunction *, Scope &scope, CallData *callData);
+
+ static void method_callLater(const BuiltinFunction *, Scope &scope, CallData *callData);
private:
void addAll();
@@ -142,18 +142,18 @@ struct ConsoleObject : Object
{
V4_OBJECT2(ConsoleObject, Object)
- static ReturnedValue method_error(CallContext *ctx);
- static ReturnedValue method_log(CallContext *ctx);
- static ReturnedValue method_info(CallContext *ctx);
- static ReturnedValue method_profile(CallContext *ctx);
- static ReturnedValue method_profileEnd(CallContext *ctx);
- static ReturnedValue method_time(CallContext *ctx);
- static ReturnedValue method_timeEnd(CallContext *ctx);
- static ReturnedValue method_count(CallContext *ctx);
- static ReturnedValue method_trace(CallContext *ctx);
- static ReturnedValue method_warn(CallContext *ctx);
- static ReturnedValue method_assert(CallContext *ctx);
- static ReturnedValue method_exception(CallContext *ctx);
+ static void method_error(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_log(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_info(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_profile(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_profileEnd(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_time(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_timeEnd(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_count(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_trace(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_warn(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_assert(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_exception(const BuiltinFunction *, Scope &scope, CallData *callData);
};
@@ -161,17 +161,17 @@ struct Q_QML_PRIVATE_EXPORT GlobalExtensions {
static void init(Object *globalObject, QJSEngine::Extensions extensions);
#if QT_CONFIG(translation)
- static ReturnedValue method_qsTranslate(CallContext *ctx);
- static ReturnedValue method_qsTranslateNoOp(CallContext *ctx);
- static ReturnedValue method_qsTr(CallContext *ctx);
- static ReturnedValue method_qsTrNoOp(CallContext *ctx);
- static ReturnedValue method_qsTrId(CallContext *ctx);
- static ReturnedValue method_qsTrIdNoOp(CallContext *ctx);
+ static void method_qsTranslate(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_qsTranslateNoOp(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_qsTr(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_qsTrNoOp(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_qsTrId(const BuiltinFunction *, Scope &scope, CallData *callData);
+ static void method_qsTrIdNoOp(const BuiltinFunction *, Scope &scope, CallData *callData);
#endif
- static ReturnedValue method_gc(CallContext *ctx);
+ static void method_gc(const BuiltinFunction *, Scope &scope, CallData *callData);
// on String:prototype
- static ReturnedValue method_string_arg(CallContext *ctx);
+ static void method_string_arg(const BuiltinFunction *, Scope &scope, CallData *callData);
};
diff --git a/src/qml/qml/v8/qv4domerrors_p.h b/src/qml/qml/v8/qv4domerrors_p.h
index faa9dd8bc7..a9bdbe01ae 100644
--- a/src/qml/qml/v8/qv4domerrors_p.h
+++ b/src/qml/qml/v8/qv4domerrors_p.h
@@ -74,11 +74,12 @@ QT_BEGIN_NAMESPACE
#define DOMEXCEPTION_VALIDATION_ERR 16
#define DOMEXCEPTION_TYPE_MISMATCH_ERR 17
-#define V4THROW_DOM(error, string) { \
+#define THROW_DOM(error, string) { \
QV4::ScopedValue v(scope, scope.engine->newString(QStringLiteral(string))); \
QV4::ScopedObject ex(scope, scope.engine->newErrorObject(v)); \
ex->put(QV4::ScopedString(scope, scope.engine->newIdentifier(QStringLiteral("code"))), QV4::ScopedValue(scope, QV4::Primitive::fromInt32(error))); \
- return ctx->engine()->throwError(ex); \
+ scope.result = scope.engine->throwError(ex); \
+ return; \
}
namespace QV4 {
diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp
index c0d75cae33..a5878dcffd 100644
--- a/src/qml/types/qqmldelegatemodel.cpp
+++ b/src/qml/types/qqmldelegatemodel.cpp
@@ -1795,24 +1795,26 @@ int QQmlDelegateModelItemMetaType::parseGroups(const QV4::Value &groups) const
return groupFlags;
}
-QV4::ReturnedValue QQmlDelegateModelItem::get_model(QV4::CallContext *ctx)
+void QQmlDelegateModelItem::get_model(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQmlDelegateModelItemObject> o(scope, ctx->thisObject().as<QQmlDelegateModelItemObject>());
- if (!o)
- return ctx->engine()->throwTypeError(QStringLiteral("Not a valid VisualData object"));
+ QV4::Scoped<QQmlDelegateModelItemObject> o(scope, callData->thisObject.as<QQmlDelegateModelItemObject>());
+ if (!o) {
+ scope.result = scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object"));
+ return;
+ }
if (!o->d()->item->metaType->model)
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
- return o->d()->item->get();
+ scope.result = o->d()->item->get();
}
-QV4::ReturnedValue QQmlDelegateModelItem::get_groups(QV4::CallContext *ctx)
+void QQmlDelegateModelItem::get_groups(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQmlDelegateModelItemObject> o(scope, ctx->thisObject().as<QQmlDelegateModelItemObject>());
- if (!o)
- return ctx->engine()->throwTypeError(QStringLiteral("Not a valid VisualData object"));
+ QV4::Scoped<QQmlDelegateModelItemObject> o(scope, callData->thisObject.as<QQmlDelegateModelItemObject>());
+ if (!o) {
+ scope.result = scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object"));
+ return;
+ }
QStringList groups;
for (int i = 1; i < o->d()->item->metaType->groupCount; ++i) {
@@ -1820,27 +1822,29 @@ QV4::ReturnedValue QQmlDelegateModelItem::get_groups(QV4::CallContext *ctx)
groups.append(o->d()->item->metaType->groupNames.at(i - 1));
}
- return scope.engine->fromVariant(groups);
+ scope.result = scope.engine->fromVariant(groups);
}
-QV4::ReturnedValue QQmlDelegateModelItem::set_groups(QV4::CallContext *ctx)
+void QQmlDelegateModelItem::set_groups(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQmlDelegateModelItemObject> o(scope, ctx->thisObject().as<QQmlDelegateModelItemObject>());
- if (!o)
- return ctx->engine()->throwTypeError(QStringLiteral("Not a valid VisualData object"));
- if (!ctx->argc())
- return ctx->engine()->throwTypeError();
+ QV4::Scoped<QQmlDelegateModelItemObject> o(scope, callData->thisObject.as<QQmlDelegateModelItemObject>());
+ if (!o) {
+ scope.result = scope.engine->throwTypeError(QStringLiteral("Not a valid VisualData object"));
+ return;
+ }
+
+ if (!callData->argc)
+ THROW_TYPE_ERROR();
if (!o->d()->item->metaType->model)
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
QQmlDelegateModelPrivate *model = QQmlDelegateModelPrivate::get(o->d()->item->metaType->model);
- const int groupFlags = model->m_cacheMetaType->parseGroups(ctx->args()[0]);
+ const int groupFlags = model->m_cacheMetaType->parseGroups(callData->args[0]);
const int cacheIndex = model->m_cache.indexOf(o->d()->item);
Compositor::iterator it = model->m_compositor.find(Compositor::Cache, cacheIndex);
model->setGroups(it, 1, Compositor::Cache, groupFlags);
- return QV4::Encode::undefined();
+ scope.result = QV4::Encode::undefined();
}
QV4::ReturnedValue QQmlDelegateModelItem::get_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &)
@@ -3234,28 +3238,25 @@ struct QQmlDelegateModelGroupChange : QV4::Object
return e->memoryManager->allocObject<QQmlDelegateModelGroupChange>();
}
- static QV4::ReturnedValue method_get_index(QV4::CallContext *ctx) {
- QV4::Scope scope(ctx);
- QV4::Scoped<QQmlDelegateModelGroupChange> that(scope, ctx->thisObject().as<QQmlDelegateModelGroupChange>());
+ static void method_get_index(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) {
+ QV4::Scoped<QQmlDelegateModelGroupChange> that(scope, callData->thisObject.as<QQmlDelegateModelGroupChange>());
if (!that)
- return ctx->engine()->throwTypeError();
- return QV4::Encode(that->d()->change.index);
+ THROW_TYPE_ERROR();
+ scope.result = 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->thisObject().as<QQmlDelegateModelGroupChange>());
+ static void method_get_count(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) {
+ QV4::Scoped<QQmlDelegateModelGroupChange> that(scope, callData->thisObject.as<QQmlDelegateModelGroupChange>());
if (!that)
- return ctx->engine()->throwTypeError();
- return QV4::Encode(that->d()->change.count);
+ THROW_TYPE_ERROR();
+ scope.result = 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->thisObject().as<QQmlDelegateModelGroupChange>());
+ static void method_get_moveId(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData) {
+ QV4::Scoped<QQmlDelegateModelGroupChange> that(scope, callData->thisObject.as<QQmlDelegateModelGroupChange>());
if (!that)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
if (that->d()->change.moveId < 0)
- return QV4::Encode::undefined();
- return QV4::Encode(that->d()->change.moveId);
+ RETURN_UNDEFINED();
+ scope.result = QV4::Encode(that->d()->change.moveId);
}
};
diff --git a/src/qml/types/qqmldelegatemodel_p_p.h b/src/qml/types/qqmldelegatemodel_p_p.h
index 4c2841b8ba..cb4a1f79ba 100644
--- a/src/qml/types/qqmldelegatemodel_p_p.h
+++ b/src/qml/types/qqmldelegatemodel_p_p.h
@@ -131,9 +131,9 @@ public:
virtual void setValue(const QString &role, const QVariant &value) { Q_UNUSED(role); Q_UNUSED(value); }
virtual bool resolveIndex(const QQmlAdaptorModel &, int) { return false; }
- static QV4::ReturnedValue get_model(QV4::CallContext *ctx);
- static QV4::ReturnedValue get_groups(QV4::CallContext *ctx);
- static QV4::ReturnedValue set_groups(QV4::CallContext *ctx);
+ static void get_model(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void get_groups(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void set_groups(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
static QV4::ReturnedValue get_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &);
static QV4::ReturnedValue set_member(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &arg);
static QV4::ReturnedValue get_index(QQmlDelegateModelItem *thisItem, uint flag, const QV4::Value &arg);
diff --git a/src/qml/types/qquickworkerscript.cpp b/src/qml/types/qquickworkerscript.cpp
index 5f716da17a..f35e17c34d 100644
--- a/src/qml/types/qquickworkerscript.cpp
+++ b/src/qml/types/qquickworkerscript.cpp
@@ -185,7 +185,7 @@ public:
int m_nextId;
- static QV4::ReturnedValue method_sendMessage(QV4::CallContext *ctx);
+ static void method_sendMessage(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
signals:
void stopThread();
@@ -292,14 +292,13 @@ QQuickWorkerScriptEnginePrivate::QQuickWorkerScriptEnginePrivate(QQmlEngine *eng
{
}
-QV4::ReturnedValue QQuickWorkerScriptEnginePrivate::method_sendMessage(QV4::CallContext *ctx)
+void QQuickWorkerScriptEnginePrivate::method_sendMessage(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- WorkerEngine *engine = (WorkerEngine*)ctx->engine()->v8Engine;
+ WorkerEngine *engine = (WorkerEngine*)scope.engine->v8Engine;
- int id = ctx->argc() > 1 ? ctx->args()[1].toInt32() : 0;
+ int id = callData->argc > 1 ? callData->args[1].toInt32() : 0;
- QV4::Scope scope(ctx);
- QV4::ScopedValue v(scope, ctx->argument(2));
+ QV4::ScopedValue v(scope, callData->argument(2));
QByteArray data = QV4::Serialize::serialize(v, scope.engine);
QMutexLocker locker(&engine->p->m_lock);
@@ -307,7 +306,7 @@ QV4::ReturnedValue QQuickWorkerScriptEnginePrivate::method_sendMessage(QV4::Call
if (script && script->owner)
QCoreApplication::postEvent(script->owner, new WorkerDataEvent(0, data));
- return QV4::Encode::undefined();
+ scope.result = QV4::Encode::undefined();
}
QV4::ReturnedValue QQuickWorkerScriptEnginePrivate::getWorker(WorkerScript *script)
diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp
index bcaedd67b4..b0c1d50907 100644
--- a/src/quick/items/context2d/qquickcontext2d.cpp
+++ b/src/quick/items/context2d/qquickcontext2d.cpp
@@ -129,10 +129,10 @@ Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok);
#define DEGREES(t) ((t) * 180.0 / M_PI)
#define CHECK_CONTEXT(r) if (!r || !r->d()->context || !r->d()->context->bufferValid()) \
- V4THROW_ERROR("Not a Context2D object");
+ THROW_GENERIC_ERROR("Not a Context2D object");
#define CHECK_CONTEXT_SETTER(r) if (!r || !r->d()->context || !r->d()->context->bufferValid()) \
- V4THROW_ERROR("Not a Context2D object");
+ THROW_GENERIC_ERROR("Not a Context2D object");
#define qClamp(val, min, max) qMin(qMax(val, min), max)
#define CHECK_RGBA(c) (c == '-' || c == '.' || (c >=0 && c <= 9))
QColor qt_color_from_string(const QV4::Value &name)
@@ -537,45 +537,45 @@ struct QQuickJSContext2D : public QV4::Object
{
V4_OBJECT2(QQuickJSContext2D, QV4::Object)
- static QV4::ReturnedValue method_get_globalAlpha(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_globalAlpha(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_globalCompositeOperation(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_globalCompositeOperation(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_fillStyle(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_fillStyle(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_fillRule(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_fillRule(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_strokeStyle(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_strokeStyle(QV4::CallContext *ctx);
-
- static QV4::ReturnedValue method_get_lineCap(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_lineCap(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_lineJoin(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_lineJoin(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_lineWidth(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_lineWidth(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_miterLimit(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_miterLimit(QV4::CallContext *ctx);
-
- static QV4::ReturnedValue method_get_shadowBlur(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_shadowBlur(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_shadowColor(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_shadowColor(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_shadowOffsetX(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_shadowOffsetX(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_shadowOffsetY(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_shadowOffsetY(QV4::CallContext *ctx);
+ static void method_get_globalAlpha(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_set_globalAlpha(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_globalCompositeOperation(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_set_globalCompositeOperation(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_fillStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_set_fillStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_fillRule(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_set_fillRule(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_strokeStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_set_strokeStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+
+ static void method_get_lineCap(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_set_lineCap(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_lineJoin(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_set_lineJoin(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_lineWidth(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_set_lineWidth(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_miterLimit(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_set_miterLimit(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+
+ static void method_get_shadowBlur(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_set_shadowBlur(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_shadowColor(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_set_shadowColor(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_shadowOffsetX(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_set_shadowOffsetX(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_shadowOffsetY(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_set_shadowOffsetY(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
// should these two be on the proto?
- static QV4::ReturnedValue method_get_path(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_path(QV4::CallContext *ctx);
-
- static QV4::ReturnedValue method_get_font(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_font(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_textAlign(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_textAlign(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_textBaseline(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_set_textBaseline(QV4::CallContext *ctx);
+ static void method_get_path(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_set_path(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+
+ static void method_get_font(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_set_font(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_textAlign(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_set_textAlign(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_textBaseline(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_set_textBaseline(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
};
DEFINE_OBJECT_VTABLE(QQuickJSContext2D);
@@ -638,50 +638,50 @@ public:
return o->d();
}
- static QV4::ReturnedValue method_get_canvas(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_restore(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_reset(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_save(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_rotate(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_scale(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_translate(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_setTransform(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_transform(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_resetTransform(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_shear(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_createLinearGradient(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_createRadialGradient(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_createConicalGradient(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_createPattern(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_clearRect(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_fillRect(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_strokeRect(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_arc(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_arcTo(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_beginPath(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_bezierCurveTo(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_clip(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_closePath(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_fill(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_lineTo(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_moveTo(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_quadraticCurveTo(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_rect(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_roundedRect(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_ellipse(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_text(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_stroke(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_isPointInPath(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_drawFocusRing(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_setCaretSelectionRect(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_caretBlinkRate(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_fillText(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_strokeText(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_measureText(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_drawImage(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_createImageData(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_getImageData(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_putImageData(QV4::CallContext *ctx);
+ static void method_get_canvas(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_restore(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_reset(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_save(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_rotate(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_scale(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_translate(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_setTransform(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_transform(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_resetTransform(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_shear(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_createLinearGradient(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_createRadialGradient(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_createConicalGradient(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_createPattern(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_clearRect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_fillRect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_strokeRect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_arc(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_arcTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_beginPath(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_bezierCurveTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_clip(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_closePath(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_fill(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_lineTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_moveTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_quadraticCurveTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_rect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_roundedRect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_ellipse(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_text(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_stroke(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_isPointInPath(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_drawFocusRing(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_setCaretSelectionRect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_caretBlinkRate(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_fillText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_strokeText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_measureText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_drawImage(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_createImageData(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_getImageData(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_putImageData(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
};
@@ -693,7 +693,7 @@ struct QQuickContext2DStyle : public QV4::Object
V4_OBJECT2(QQuickContext2DStyle, QV4::Object)
V4_NEEDS_DESTROY
- static QV4::ReturnedValue gradient_proto_addColorStop(QV4::CallContext *ctx);
+ static void gradient_proto_addColorStop(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
};
@@ -903,7 +903,7 @@ struct QQuickJSContext2DPixelData : public QV4::Object
static QV4::ReturnedValue getIndexed(const QV4::Managed *m, uint index, bool *hasProperty);
static void putIndexed(QV4::Managed *m, uint index, const QV4::Value &value);
- static QV4::ReturnedValue proto_get_length(QV4::CallContext *ctx);
+ static void proto_get_length(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
};
void QV4::Heap::QQuickJSContext2DPixelData::init()
@@ -921,9 +921,9 @@ struct QQuickJSContext2DImageData : public QV4::Object
{
V4_OBJECT2(QQuickJSContext2DImageData, QV4::Object)
- static QV4::ReturnedValue method_get_width(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_height(QV4::CallContext *ctx);
- static QV4::ReturnedValue method_get_data(QV4::CallContext *ctx);
+ static void method_get_width(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_height(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
+ static void method_get_data(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData);
static void markObjects(QV4::Heap::Base *that, QV4::ExecutionEngine *engine) {
static_cast<QQuickJSContext2DImageData::Data *>(that)->pixelData.mark(engine);
@@ -975,13 +975,12 @@ static QV4::ReturnedValue qt_create_image_data(qreal w, qreal h, QV4::ExecutionE
This property is read only.
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_get_canvas(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_get_canvas(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- return QV4::QObjectWrapper::wrap(scope.engine, r->d()->context->canvas());
+ scope.result = QV4::QObjectWrapper::wrap(scope.engine, r->d()->context->canvas());
}
/*!
@@ -990,29 +989,27 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_get_canvas(QV4::CallContex
\sa save()
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_restore(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_restore(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
r->d()->context->popState();
- return ctx->thisObject().asReturnedValue();
+ scope.result = callData->thisObject.asReturnedValue();
}
/*!
\qmlmethod object QtQuick::Context2D::reset()
Resets the context state and properties to the default values.
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_reset(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_reset(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
r->d()->context->reset();
- return ctx->thisObject().asReturnedValue();
+ scope.result = callData->thisObject.asReturnedValue();
}
/*!
@@ -1045,15 +1042,14 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_reset(QV4::CallContext *ct
The current path is NOT part of the drawing state. The path can be reset by
invoking the beginPath() method.
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_save(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_save(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
r->d()->context->pushState();
- return ctx->thisObject().asReturnedValue();
+ scope.result = callData->thisObject;
}
// transformations
@@ -1074,15 +1070,14 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_save(QV4::CallContext *ctx
where the \a angle of rotation is in radians.
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_rotate(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_rotate(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (ctx->argc() >= 1)
- r->d()->context->rotate(ctx->args()[0].toNumber());
- return ctx->thisObject().asReturnedValue();
+ if (callData->argc >= 1)
+ r->d()->context->rotate(callData->args[0].toNumber());
+ scope.result = callData->thisObject;
}
/*!
@@ -1102,16 +1097,16 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_rotate(QV4::CallContext *c
\image qml-item-canvas-scale.png
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_scale(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_scale(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (ctx->argc() >= 2)
- r->d()->context->scale(ctx->args()[0].toNumber(), ctx->args()[1].toNumber());
- return ctx->thisObject().asReturnedValue();
+ if (callData->argc >= 2)
+ r->d()->context->scale(callData->args[0].toNumber(), callData->args[1].toNumber());
+ scope.result = callData->thisObject;
+
}
/*!
@@ -1148,22 +1143,22 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_scale(QV4::CallContext *ct
\sa transform()
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_setTransform(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_setTransform(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (ctx->argc() >= 6)
- r->d()->context->setTransform( ctx->args()[0].toNumber()
- , ctx->args()[1].toNumber()
- , ctx->args()[2].toNumber()
- , ctx->args()[3].toNumber()
- , ctx->args()[4].toNumber()
- , ctx->args()[5].toNumber());
+ if (callData->argc >= 6)
+ r->d()->context->setTransform( callData->args[0].toNumber()
+ , callData->args[1].toNumber()
+ , callData->args[2].toNumber()
+ , callData->args[3].toNumber()
+ , callData->args[4].toNumber()
+ , callData->args[5].toNumber());
+
+ scope.result = callData->thisObject;
- return ctx->thisObject().asReturnedValue();
}
/*!
@@ -1177,21 +1172,21 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_setTransform(QV4::CallCont
\sa setTransform()
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_transform(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_transform(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (ctx->argc() >= 6)
- r->d()->context->transform( ctx->args()[0].toNumber()
- , ctx->args()[1].toNumber()
- , ctx->args()[2].toNumber()
- , ctx->args()[3].toNumber()
- , ctx->args()[4].toNumber()
- , ctx->args()[5].toNumber());
+ if (callData->argc >= 6)
+ r->d()->context->transform( callData->args[0].toNumber()
+ , callData->args[1].toNumber()
+ , callData->args[2].toNumber()
+ , callData->args[3].toNumber()
+ , callData->args[4].toNumber()
+ , callData->args[5].toNumber());
+
+ scope.result = callData->thisObject;
- return ctx->thisObject().asReturnedValue();
}
/*!
@@ -1203,15 +1198,15 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_transform(QV4::CallContext
Translating the origin enables you to draw patterns of different objects on the canvas
without having to measure the coordinates manually for each shape.
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_translate(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_translate(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (ctx->argc() >= 2)
- r->d()->context->translate(ctx->args()[0].toNumber(), ctx->args()[1].toNumber());
- return ctx->thisObject().asReturnedValue();
+ if (callData->argc >= 2)
+ r->d()->context->translate(callData->args[0].toNumber(), callData->args[1].toNumber());
+ scope.result = callData->thisObject;
+
}
@@ -1223,15 +1218,15 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_translate(QV4::CallContext
\sa transform(), setTransform(), reset()
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_resetTransform(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_resetTransform(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
r->d()->context->setTransform(1, 0, 0, 1, 0, 0);
- return ctx->thisObject().asReturnedValue();
+ scope.result = callData->thisObject;
+
}
@@ -1241,16 +1236,16 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_resetTransform(QV4::CallCo
Shears the transformation matrix by \a sh in the horizontal direction and
\a sv in the vertical direction.
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_shear(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_shear(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (ctx->argc() >= 2)
- r->d()->context->shear(ctx->args()[0].toNumber(), ctx->args()[1].toNumber());
+ if (callData->argc >= 2)
+ r->d()->context->shear(callData->args[0].toNumber(), callData->args[1].toNumber());
+
+ scope.result = callData->thisObject;
- return ctx->thisObject().asReturnedValue();
}
// compositing
@@ -1261,31 +1256,30 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_shear(QV4::CallContext *ct
The value must be in the range from \c 0.0 (fully transparent) to \c 1.0 (fully opaque).
The default value is \c 1.0.
*/
-QV4::ReturnedValue QQuickJSContext2D::method_get_globalAlpha(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_get_globalAlpha(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- return QV4::Encode(r->d()->context->state.globalAlpha);
+ scope.result = QV4::Encode(r->d()->context->state.globalAlpha);
}
-QV4::ReturnedValue QQuickJSContext2D::method_set_globalAlpha(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_set_globalAlpha(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT_SETTER(r)
- double globalAlpha = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
+ double globalAlpha = callData->argc ? callData->args[0].toNumber() : qt_qnan();
+
+ scope.result = QV4::Encode::undefined();
if (!qt_is_finite(globalAlpha))
- return QV4::Encode::undefined();
+ return;
if (globalAlpha >= 0.0 && globalAlpha <= 1.0 && r->d()->context->state.globalAlpha != globalAlpha) {
r->d()->context->state.globalAlpha = globalAlpha;
r->d()->context->buffer()->setGlobalAlpha(r->d()->context->state.globalAlpha);
}
- return QV4::Encode::undefined();
}
/*!
@@ -1314,34 +1308,33 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_globalAlpha(QV4::CallContext *c
extension composition modes are provided as "vendorName-operationName" syntax, for example: QPainter::CompositionMode_Exclusion is provided as
"qt-exclusion".
*/
-QV4::ReturnedValue QQuickJSContext2D::method_get_globalCompositeOperation(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_get_globalCompositeOperation(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- return QV4::Encode(scope.engine->newString(qt_composite_mode_to_string(r->d()->context->state.globalCompositeOperation)));
+ scope.result = scope.engine->newString(qt_composite_mode_to_string(r->d()->context->state.globalCompositeOperation));
}
-QV4::ReturnedValue QQuickJSContext2D::method_set_globalCompositeOperation(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_set_globalCompositeOperation(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT_SETTER(r)
- if (!ctx->argc())
- return ctx->engine()->throwTypeError();
+ if (!callData->argc)
+ THROW_TYPE_ERROR();
- QString mode = ctx->args()[0].toQString();
+ scope.result = QV4::Encode::undefined();
+
+ QString mode = callData->args[0].toQString();
QPainter::CompositionMode cm = qt_composite_mode_from_string(mode);
if (cm == QPainter::CompositionMode_SourceOver && mode != QLatin1String("source-over"))
- return QV4::Encode::undefined();
+ return;
if (cm != r->d()->context->state.globalCompositeOperation) {
r->d()->context->state.globalCompositeOperation = cm;
r->d()->context->buffer()->setGlobalCompositeOperation(cm);
}
- return QV4::Encode::undefined();
}
// colors and styles
@@ -1367,34 +1360,32 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_globalCompositeOperation(QV4::C
\sa createPattern()
\sa strokeStyle
*/
-QV4::ReturnedValue QQuickJSContext2D::method_get_fillStyle(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_get_fillStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
QColor color = r->d()->context->state.fillStyle.color();
if (color.isValid()) {
if (color.alpha() == 255)
- return QV4::Encode(scope.engine->newString(color.name()));
+ RETURN_RESULT(scope.engine->newString(color.name()));
QString alphaString = QString::number(color.alphaF(), 'f');
while (alphaString.endsWith(QLatin1Char('0')))
alphaString.chop(1);
if (alphaString.endsWith(QLatin1Char('.')))
alphaString += QLatin1Char('0');
QString str = QString::fromLatin1("rgba(%1, %2, %3, %4)").arg(color.red()).arg(color.green()).arg(color.blue()).arg(alphaString);
- return QV4::Encode(scope.engine->newString(str));
+ RETURN_RESULT(scope.engine->newString(str));
}
- return r->d()->context->m_fillStyle.value();
+ scope.result = r->d()->context->m_fillStyle.value();
}
-QV4::ReturnedValue QQuickJSContext2D::method_set_fillStyle(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_set_fillStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT_SETTER(r)
- QV4::ScopedValue value(scope, ctx->argument(0));
+ QV4::ScopedValue value(scope, callData->argument(0));
if (value->as<Object>()) {
QColor color = scope.engine->toVariant(value, qMetaTypeId<QColor>()).value<QColor>();
@@ -1420,7 +1411,7 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_fillStyle(QV4::CallContext *ctx
r->d()->context->m_fillStyle.set(scope.engine, value);
}
}
- return QV4::Encode::undefined();
+ scope.result = QV4::Encode::undefined();
}
/*!
\qmlproperty enumeration QtQuick::Context2D::fillRule
@@ -1434,22 +1425,20 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_fillStyle(QV4::CallContext *ctx
\sa fillStyle
*/
-QV4::ReturnedValue QQuickJSContext2D::method_get_fillRule(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_get_fillRule(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- return scope.engine->fromVariant(r->d()->context->state.fillRule);
+ scope.result = scope.engine->fromVariant(r->d()->context->state.fillRule);
}
-QV4::ReturnedValue QQuickJSContext2D::method_set_fillRule(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_set_fillRule(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT_SETTER(r)
- QV4::ScopedValue value(scope, ctx->argument(0));
+ QV4::ScopedValue value(scope, callData->argument(0));
if ((value->isString() && value->toQString() == QLatin1String("WindingFill"))
|| (value->isInt32() && value->integerValue() == Qt::WindingFill)) {
@@ -1461,7 +1450,7 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_fillRule(QV4::CallContext *ctx)
//error
}
r->d()->context->m_path.setFillRule(r->d()->context->state.fillRule);
- return QV4::Encode::undefined();
+ scope.result = QV4::Encode::undefined();
}
/*!
\qmlproperty variant QtQuick::Context2D::strokeStyle
@@ -1476,34 +1465,32 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_fillRule(QV4::CallContext *ctx)
\sa createPattern()
\sa fillStyle
*/
-QV4::ReturnedValue QQuickJSContext2D::method_get_strokeStyle(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_get_strokeStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
QColor color = r->d()->context->state.strokeStyle.color();
if (color.isValid()) {
if (color.alpha() == 255)
- return QV4::Encode(scope.engine->newString(color.name()));
+ RETURN_RESULT(scope.engine->newString(color.name()));
QString alphaString = QString::number(color.alphaF(), 'f');
while (alphaString.endsWith(QLatin1Char('0')))
alphaString.chop(1);
if (alphaString.endsWith(QLatin1Char('.')))
alphaString += QLatin1Char('0');
QString str = QString::fromLatin1("rgba(%1, %2, %3, %4)").arg(color.red()).arg(color.green()).arg(color.blue()).arg(alphaString);
- return QV4::Encode(scope.engine->newString(str));
+ RETURN_RESULT(scope.engine->newString(str));
}
- return r->d()->context->m_strokeStyle.value();
+ scope.result = r->d()->context->m_strokeStyle.value();
}
-QV4::ReturnedValue QQuickJSContext2D::method_set_strokeStyle(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_set_strokeStyle(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT_SETTER(r)
- QV4::ScopedValue value(scope, ctx->argument(0));
+ QV4::ScopedValue value(scope, callData->argument(0));
if (value->as<Object>()) {
QColor color = scope.engine->toVariant(value, qMetaTypeId<QColor>()).value<QColor>();
@@ -1530,7 +1517,7 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_strokeStyle(QV4::CallContext *c
r->d()->context->m_strokeStyle.set(scope.engine, value);
}
}
- return QV4::Encode::undefined();
+ scope.result = QV4::Encode::undefined();
}
/*!
@@ -1550,23 +1537,22 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_strokeStyle(QV4::CallContext *c
\sa strokeStyle
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_createLinearGradient(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_createLinearGradient(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (ctx->argc() >= 4) {
- qreal x0 = ctx->args()[0].toNumber();
- qreal y0 = ctx->args()[1].toNumber();
- qreal x1 = ctx->args()[2].toNumber();
- qreal y1 = ctx->args()[3].toNumber();
+ if (callData->argc >= 4) {
+ qreal x0 = callData->args[0].toNumber();
+ qreal y0 = callData->args[1].toNumber();
+ qreal x1 = callData->args[2].toNumber();
+ qreal y1 = callData->args[3].toNumber();
if (!qt_is_finite(x0)
|| !qt_is_finite(y0)
|| !qt_is_finite(x1)
|| !qt_is_finite(y1)) {
- V4THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "createLinearGradient(): Incorrect arguments")
+ THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "createLinearGradient(): Incorrect arguments")
}
QQuickContext2DEngineData *ed = engineData(scope.engine);
@@ -1574,10 +1560,11 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createLinearGradient(QV4::
QV4::ScopedObject p(scope, ed->gradientProto.value());
gradient->setPrototype(p);
*gradient->d()->brush = QLinearGradient(x0, y0, x1, y1);
- return gradient.asReturnedValue();
+ RETURN_RESULT(gradient);
}
- return ctx->thisObject().asReturnedValue();
+ scope.result = callData->thisObject;
+
}
/*!
@@ -1593,19 +1580,18 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createLinearGradient(QV4::
\sa strokeStyle
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_createRadialGradient(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_createRadialGradient(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (ctx->argc() >= 6) {
- qreal x0 = ctx->args()[0].toNumber();
- qreal y0 = ctx->args()[1].toNumber();
- qreal r0 = ctx->args()[2].toNumber();
- qreal x1 = ctx->args()[3].toNumber();
- qreal y1 = ctx->args()[4].toNumber();
- qreal r1 = ctx->args()[5].toNumber();
+ if (callData->argc >= 6) {
+ qreal x0 = callData->args[0].toNumber();
+ qreal y0 = callData->args[1].toNumber();
+ qreal r0 = callData->args[2].toNumber();
+ qreal x1 = callData->args[3].toNumber();
+ qreal y1 = callData->args[4].toNumber();
+ qreal r1 = callData->args[5].toNumber();
if (!qt_is_finite(x0)
|| !qt_is_finite(y0)
@@ -1613,11 +1599,11 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createRadialGradient(QV4::
|| !qt_is_finite(r0)
|| !qt_is_finite(r1)
|| !qt_is_finite(y1)) {
- V4THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "createRadialGradient(): Incorrect arguments")
+ THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "createRadialGradient(): Incorrect arguments")
}
if (r0 < 0 || r1 < 0)
- V4THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "createRadialGradient(): Incorrect arguments")
+ THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "createRadialGradient(): Incorrect arguments")
QQuickContext2DEngineData *ed = engineData(scope.engine);
@@ -1625,10 +1611,11 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createRadialGradient(QV4::
QV4::ScopedObject p(scope, ed->gradientProto.value());
gradient->setPrototype(p);
*gradient->d()->brush = QRadialGradient(QPointF(x1, y1), r0+r1, QPointF(x0, y0));
- return gradient.asReturnedValue();
+ RETURN_RESULT(gradient);
}
- return ctx->thisObject().asReturnedValue();
+ scope.result = callData->thisObject;
+
}
/*!
@@ -1644,22 +1631,21 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createRadialGradient(QV4::
\sa strokeStyle
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_createConicalGradient(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_createConicalGradient(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (ctx->argc() >= 3) {
- qreal x = ctx->args()[0].toNumber();
- qreal y = ctx->args()[1].toNumber();
- qreal angle = DEGREES(ctx->args()[2].toNumber());
+ if (callData->argc >= 3) {
+ qreal x = callData->args[0].toNumber();
+ qreal y = callData->args[1].toNumber();
+ qreal angle = DEGREES(callData->args[2].toNumber());
if (!qt_is_finite(x) || !qt_is_finite(y)) {
- V4THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "createConicalGradient(): Incorrect arguments");
+ THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "createConicalGradient(): Incorrect arguments");
}
if (!qt_is_finite(angle)) {
- V4THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "createConicalGradient(): Incorrect arguments");
+ THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "createConicalGradient(): Incorrect arguments");
}
QQuickContext2DEngineData *ed = engineData(scope.engine);
@@ -1668,10 +1654,11 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createConicalGradient(QV4:
QV4::ScopedObject p(scope, ed->gradientProto.value());
gradient->setPrototype(p);
*gradient->d()->brush = QConicalGradient(x, y, angle);
- return gradient.asReturnedValue();
+ RETURN_RESULT(gradient);
}
- return ctx->thisObject().asReturnedValue();
+ scope.result = callData->thisObject;
+
}
/*!
\qmlmethod variant QtQuick::Context2D::createPattern(color color, enumeration patternMode)
@@ -1716,18 +1703,17 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createConicalGradient(QV4:
\sa strokeStyle
\sa fillStyle
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_createPattern(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_createPattern(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->argc() >= 2) {
+ if (callData->argc >= 2) {
QV4::Scoped<QQuickContext2DStyle> pattern(scope, scope.engine->memoryManager->allocObject<QQuickContext2DStyle>());
- QColor color = scope.engine->toVariant(ctx->args()[0], qMetaTypeId<QColor>()).value<QColor>();
+ QColor color = scope.engine->toVariant(callData->args[0], qMetaTypeId<QColor>()).value<QColor>();
if (color.isValid()) {
- int patternMode = ctx->args()[1].toInt32();
+ int patternMode = callData->args[1].toInt32();
Qt::BrushStyle style = Qt::SolidPattern;
if (patternMode >= 0 && patternMode < Qt::LinearGradientPattern) {
style = static_cast<Qt::BrushStyle>(patternMode);
@@ -1736,20 +1722,20 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createPattern(QV4::CallCon
} else {
QImage patternTexture;
- if (const QV4::Object *o = ctx->args()[0].as<Object>()) {
+ if (const QV4::Object *o = callData->args[0].as<Object>()) {
QV4::ScopedString s(scope, scope.engine->newString(QStringLiteral("data")));
QV4::Scoped<QQuickJSContext2DPixelData> pixelData(scope, o->get(s));
if (!!pixelData) {
patternTexture = *pixelData->d()->image;
}
} else {
- patternTexture = r->d()->context->createPixmap(QUrl(ctx->args()[0].toQStringNoThrow()))->image();
+ patternTexture = r->d()->context->createPixmap(QUrl(callData->args[0].toQStringNoThrow()))->image();
}
if (!patternTexture.isNull()) {
pattern->d()->brush->setTextureImage(patternTexture);
- QString repetition = ctx->args()[1].toQStringNoThrow();
+ QString repetition = callData->args[1].toQStringNoThrow();
if (repetition == QLatin1String("repeat") || repetition.isEmpty()) {
pattern->d()->patternRepeatX = true;
pattern->d()->patternRepeatY = true;
@@ -1769,10 +1755,10 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createPattern(QV4::CallCon
}
}
- return pattern.asReturnedValue();
+ RETURN_RESULT(pattern);
}
- return QV4::Encode::undefined();
+ scope.result = QV4::Encode::undefined();
}
// line styles
@@ -1787,31 +1773,29 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createPattern(QV4::CallCon
\endlist
Other values are ignored.
*/
-QV4::ReturnedValue QQuickJSContext2D::method_get_lineCap(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_get_lineCap(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
switch (r->d()->context->state.lineCap) {
case Qt::RoundCap:
- return QV4::Encode(scope.engine->newString(QStringLiteral("round")));
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("round")));
case Qt::SquareCap:
- return QV4::Encode(scope.engine->newString(QStringLiteral("square")));
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("square")));
case Qt::FlatCap:
default:
break;
}
- return QV4::Encode(scope.engine->newString(QStringLiteral("butt")));
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("butt")));
}
-QV4::ReturnedValue QQuickJSContext2D::method_set_lineCap(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_set_lineCap(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT_SETTER(r)
- QString lineCap = ctx->args()[0].toQString();
+ QString lineCap = callData->args[0].toQString();
Qt::PenCapStyle cap;
if (lineCap == QLatin1String("round"))
cap = Qt::RoundCap;
@@ -1820,13 +1804,13 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_lineCap(QV4::CallContext *ctx)
else if (lineCap == QLatin1String("square"))
cap = Qt::SquareCap;
else
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
if (cap != r->d()->context->state.lineCap) {
r->d()->context->state.lineCap = cap;
r->d()->context->buffer()->setLineCap(cap);
}
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
/*!
@@ -1843,34 +1827,32 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_lineCap(QV4::CallContext *ctx)
\endlist
Other values are ignored.
*/
-QV4::ReturnedValue QQuickJSContext2D::method_get_lineJoin(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_get_lineJoin(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
switch (r->d()->context->state.lineJoin) {
case Qt::RoundJoin:
- return QV4::Encode(scope.engine->newString(QStringLiteral("round")));
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("round")));
case Qt::BevelJoin:
- return QV4::Encode(scope.engine->newString(QStringLiteral("bevel")));
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("bevel")));
case Qt::MiterJoin:
default:
break;
}
- return QV4::Encode(scope.engine->newString(QStringLiteral("miter")));
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("miter")));
}
-QV4::ReturnedValue QQuickJSContext2D::method_set_lineJoin(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_set_lineJoin(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT_SETTER(r)
- if (!ctx->argc())
- return ctx->engine()->throwTypeError();
+ if (!callData->argc)
+ THROW_TYPE_ERROR();
- QString lineJoin = ctx->args()[0].toQString();
+ QString lineJoin = callData->args[0].toQString();
Qt::PenJoinStyle join;
if (lineJoin == QLatin1String("round"))
join = Qt::RoundJoin;
@@ -1879,41 +1861,39 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_lineJoin(QV4::CallContext *ctx)
else if (lineJoin == QLatin1String("miter"))
join = Qt::SvgMiterJoin;
else
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
if (join != r->d()->context->state.lineJoin) {
r->d()->context->state.lineJoin = join;
r->d()->context->buffer()->setLineJoin(join);
}
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
/*!
\qmlproperty real QtQuick::Context2D::lineWidth
Holds the current line width. Values that are not finite values greater than zero are ignored.
*/
-QV4::ReturnedValue QQuickJSContext2D::method_get_lineWidth(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_get_lineWidth(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- return QV4::Encode(r->d()->context->state.lineWidth);
+ RETURN_RESULT(r->d()->context->state.lineWidth);
}
-QV4::ReturnedValue QQuickJSContext2D::method_set_lineWidth(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_set_lineWidth(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT_SETTER(r)
- qreal w = ctx->argc() ? ctx->args()[0].toNumber() : -1;
+ qreal w = callData->argc ? callData->args[0].toNumber() : -1;
if (w > 0 && qt_is_finite(w) && w != r->d()->context->state.lineWidth) {
r->d()->context->state.lineWidth = w;
r->d()->context->buffer()->setLineWidth(w);
}
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
/*!
@@ -1921,28 +1901,26 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_lineWidth(QV4::CallContext *ctx
Holds the current miter limit ratio.
The default miter limit value is 10.0.
*/
-QV4::ReturnedValue QQuickJSContext2D::method_get_miterLimit(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_get_miterLimit(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- return QV4::Encode(r->d()->context->state.miterLimit);
+ RETURN_RESULT(r->d()->context->state.miterLimit);
}
-QV4::ReturnedValue QQuickJSContext2D::method_set_miterLimit(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_set_miterLimit(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT_SETTER(r)
- qreal ml = ctx->argc() ? ctx->args()[0].toNumber() : -1;
+ qreal ml = callData->argc ? callData->args[0].toNumber() : -1;
if (ml > 0 && qt_is_finite(ml) && ml != r->d()->context->state.miterLimit) {
r->d()->context->state.miterLimit = ml;
r->d()->context->buffer()->setMiterLimit(ml);
}
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
// shadows
@@ -1950,58 +1928,54 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_miterLimit(QV4::CallContext *ct
\qmlproperty real QtQuick::Context2D::shadowBlur
Holds the current level of blur applied to shadows
*/
-QV4::ReturnedValue QQuickJSContext2D::method_get_shadowBlur(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_get_shadowBlur(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- return QV4::Encode(r->d()->context->state.shadowBlur);
+ RETURN_RESULT(r->d()->context->state.shadowBlur);
}
-QV4::ReturnedValue QQuickJSContext2D::method_set_shadowBlur(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_set_shadowBlur(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT_SETTER(r)
- qreal blur = ctx->argc() ? ctx->args()[0].toNumber() : -1;
+ qreal blur = callData->argc ? callData->args[0].toNumber() : -1;
if (blur > 0 && qt_is_finite(blur) && blur != r->d()->context->state.shadowBlur) {
r->d()->context->state.shadowBlur = blur;
r->d()->context->buffer()->setShadowBlur(blur);
}
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
/*!
\qmlproperty string QtQuick::Context2D::shadowColor
Holds the current shadow color.
*/
-QV4::ReturnedValue QQuickJSContext2D::method_get_shadowColor(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_get_shadowColor(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- return QV4::Encode(scope.engine->newString(r->d()->context->state.shadowColor.name()));
+ RETURN_RESULT(scope.engine->newString(r->d()->context->state.shadowColor.name()));
}
-QV4::ReturnedValue QQuickJSContext2D::method_set_shadowColor(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_set_shadowColor(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT_SETTER(r)
QColor color;
- if (ctx->argc())
- color = qt_color_from_string(ctx->args()[0]);
+ if (callData->argc)
+ color = qt_color_from_string(callData->args[0]);
if (color.isValid() && color != r->d()->context->state.shadowColor) {
r->d()->context->state.shadowColor = color;
r->d()->context->buffer()->setShadowColor(color);
}
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
@@ -2011,27 +1985,25 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_shadowColor(QV4::CallContext *c
\sa shadowOffsetY
*/
-QV4::ReturnedValue QQuickJSContext2D::method_get_shadowOffsetX(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_get_shadowOffsetX(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- return QV4::Encode(r->d()->context->state.shadowOffsetX);
+ RETURN_RESULT(r->d()->context->state.shadowOffsetX);
}
-QV4::ReturnedValue QQuickJSContext2D::method_set_shadowOffsetX(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_set_shadowOffsetX(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT_SETTER(r)
- qreal offsetX = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
+ qreal offsetX = callData->argc ? callData->args[0].toNumber() : qt_qnan();
if (qt_is_finite(offsetX) && offsetX != r->d()->context->state.shadowOffsetX) {
r->d()->context->state.shadowOffsetX = offsetX;
r->d()->context->buffer()->setShadowOffsetX(offsetX);
}
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
/*!
\qmlproperty qreal QtQuick::Context2D::shadowOffsetY
@@ -2039,45 +2011,41 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_shadowOffsetX(QV4::CallContext
\sa shadowOffsetX
*/
-QV4::ReturnedValue QQuickJSContext2D::method_get_shadowOffsetY(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_get_shadowOffsetY(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- return QV4::Encode(r->d()->context->state.shadowOffsetY);
+ RETURN_RESULT(r->d()->context->state.shadowOffsetY);
}
-QV4::ReturnedValue QQuickJSContext2D::method_set_shadowOffsetY(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_set_shadowOffsetY(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT_SETTER(r)
- qreal offsetY = ctx->argc() ? ctx->args()[0].toNumber() : qt_qnan();
+ qreal offsetY = callData->argc ? callData->args[0].toNumber() : qt_qnan();
if (qt_is_finite(offsetY) && offsetY != r->d()->context->state.shadowOffsetY) {
r->d()->context->state.shadowOffsetY = offsetY;
r->d()->context->buffer()->setShadowOffsetY(offsetY);
}
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
-QV4::ReturnedValue QQuickJSContext2D::method_get_path(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_get_path(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- return r->d()->context->m_v4path.value();
+ scope.result = r->d()->context->m_v4path.value();
}
-QV4::ReturnedValue QQuickJSContext2D::method_set_path(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_set_path(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT_SETTER(r)
- QV4::ScopedValue value(scope, ctx->argument(0));
+ QV4::ScopedValue value(scope, callData->argument(0));
r->d()->context->beginPath();
QV4::Scoped<QV4::QObjectWrapper> qobjectWrapper(scope, value);
if (!!qobjectWrapper) {
@@ -2088,7 +2056,7 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_path(QV4::CallContext *ctx)
QQuickSvgParser::parsePathDataFast(path, r->d()->context->m_path);
}
r->d()->context->m_v4path.set(scope.engine, value);
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
//rects
@@ -2096,20 +2064,20 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_path(QV4::CallContext *ctx)
\qmlmethod object QtQuick::Context2D::clearRect(real x, real y, real w, real h)
Clears all pixels on the canvas in the given rectangle to transparent black.
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_clearRect(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_clearRect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->argc() >= 4)
- r->d()->context->clearRect(ctx->args()[0].toNumber(),
- ctx->args()[1].toNumber(),
- ctx->args()[2].toNumber(),
- ctx->args()[3].toNumber());
+ if (callData->argc >= 4)
+ r->d()->context->clearRect(callData->args[0].toNumber(),
+ callData->args[1].toNumber(),
+ callData->args[2].toNumber(),
+ callData->args[3].toNumber());
+
+ scope.result = callData->thisObject;
- return ctx->thisObject().asReturnedValue();
}
/*!
\qmlmethod object QtQuick::Context2D::fillRect(real x, real y, real w, real h)
@@ -2117,15 +2085,15 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_clearRect(QV4::CallContext
\sa fillStyle
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_fillRect(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_fillRect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->argc() >= 4)
- r->d()->context->fillRect(ctx->args()[0].toNumber(), ctx->args()[1].toNumber(), ctx->args()[2].toNumber(), ctx->args()[3].toNumber());
- return ctx->thisObject().asReturnedValue();
+ if (callData->argc >= 4)
+ r->d()->context->fillRect(callData->args[0].toNumber(), callData->args[1].toNumber(), callData->args[2].toNumber(), callData->args[3].toNumber());
+ scope.result = callData->thisObject;
+
}
/*!
@@ -2138,16 +2106,16 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_fillRect(QV4::CallContext
\sa lineJoin
\sa miterLimit
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_strokeRect(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_strokeRect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->argc() >= 4)
- r->d()->context->strokeRect(ctx->args()[0].toNumber(), ctx->args()[1].toNumber(), ctx->args()[2].toNumber(), ctx->args()[3].toNumber());
+ if (callData->argc >= 4)
+ r->d()->context->strokeRect(callData->args[0].toNumber(), callData->args[1].toNumber(), callData->args[2].toNumber(), callData->args[3].toNumber());
+
+ scope.result = callData->thisObject;
- return ctx->thisObject().asReturnedValue();
}
// Complex shapes (paths) API
@@ -2171,32 +2139,32 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_strokeRect(QV4::CallContex
\sa arcTo, {http://www.w3.org/TR/2dcontext/#dom-context-2d-arc}{W3C's 2D
Context Standard for arc()}
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_arc(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_arc(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->argc() >= 5) {
+ if (callData->argc >= 5) {
bool antiClockwise = false;
- if (ctx->argc() == 6)
- antiClockwise = ctx->args()[5].toBoolean();
+ if (callData->argc == 6)
+ antiClockwise = callData->args[5].toBoolean();
- qreal radius = ctx->args()[2].toNumber();
+ qreal radius = callData->args[2].toNumber();
if (qt_is_finite(radius) && radius < 0)
- V4THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "Incorrect argument radius");
+ THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "Incorrect argument radius");
- r->d()->context->arc(ctx->args()[0].toNumber(),
- ctx->args()[1].toNumber(),
+ r->d()->context->arc(callData->args[0].toNumber(),
+ callData->args[1].toNumber(),
radius,
- ctx->args()[3].toNumber(),
- ctx->args()[4].toNumber(),
+ callData->args[3].toNumber(),
+ callData->args[4].toNumber(),
antiClockwise);
}
- return ctx->thisObject().asReturnedValue();
+ scope.result = callData->thisObject;
+
}
/*!
@@ -2222,26 +2190,26 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_arc(QV4::CallContext *ctx)
\sa arc, {http://www.w3.org/TR/2dcontext/#dom-context-2d-arcto}{W3C's 2D
Context Standard for arcTo()}
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_arcTo(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_arcTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->argc() >= 5) {
- qreal radius = ctx->args()[4].toNumber();
+ if (callData->argc >= 5) {
+ qreal radius = callData->args[4].toNumber();
if (qt_is_finite(radius) && radius < 0)
- V4THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "Incorrect argument radius");
+ THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "Incorrect argument radius");
- r->d()->context->arcTo(ctx->args()[0].toNumber(),
- ctx->args()[1].toNumber(),
- ctx->args()[2].toNumber(),
- ctx->args()[3].toNumber(),
+ r->d()->context->arcTo(callData->args[0].toNumber(),
+ callData->args[1].toNumber(),
+ callData->args[2].toNumber(),
+ callData->args[3].toNumber(),
radius);
}
- return ctx->thisObject().asReturnedValue();
+ scope.result = callData->thisObject;
+
}
/*!
@@ -2249,15 +2217,15 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_arcTo(QV4::CallContext *ct
Resets the current path to a new path.
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_beginPath(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_beginPath(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
r->d()->context->beginPath();
- return ctx->thisObject().asReturnedValue();
+ scope.result = callData->thisObject;
+
}
/*!
@@ -2279,28 +2247,26 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_beginPath(QV4::CallContext
\sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-beziercurveto}{W3C 2d context standard for bezierCurveTo}
\sa {http://www.openrise.com/lab/FlowerPower/}{The beautiful flower demo by using bezierCurveTo}
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_bezierCurveTo(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_bezierCurveTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
+ scope.result = callData->thisObject;
- if (ctx->argc() >= 6) {
- qreal cp1x = ctx->args()[0].toNumber();
- qreal cp1y = ctx->args()[1].toNumber();
- qreal cp2x = ctx->args()[2].toNumber();
- qreal cp2y = ctx->args()[3].toNumber();
- qreal x = ctx->args()[4].toNumber();
- qreal y = ctx->args()[5].toNumber();
+ if (callData->argc >= 6) {
+ qreal cp1x = callData->args[0].toNumber();
+ qreal cp1y = callData->args[1].toNumber();
+ qreal cp2x = callData->args[2].toNumber();
+ qreal cp2y = callData->args[3].toNumber();
+ qreal x = callData->args[4].toNumber();
+ qreal y = callData->args[5].toNumber();
if (!qt_is_finite(cp1x) || !qt_is_finite(cp1y) || !qt_is_finite(cp2x) || !qt_is_finite(cp2y) || !qt_is_finite(x) || !qt_is_finite(y))
- return ctx->thisObject().asReturnedValue();
+ return;
r->d()->context->bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
}
-
- return ctx->thisObject().asReturnedValue();
}
/*!
@@ -2327,14 +2293,13 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_bezierCurveTo(QV4::CallCon
\sa fill()
\sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-clip}{W3C 2d context standard for clip}
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_clip(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_clip(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
r->d()->context->clip();
- return ctx->thisObject().asReturnedValue();
+ scope.result = callData->thisObject;
}
/*!
@@ -2344,16 +2309,15 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_clip(QV4::CallContext *ctx
\sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-closepath}{W3C 2d context standard for closePath}
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_closePath(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_closePath(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
r->d()->context->closePath();
- return ctx->thisObject().asReturnedValue();
+ scope.result = callData->thisObject;
}
/*!
@@ -2365,13 +2329,12 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_closePath(QV4::CallContext
\sa fillStyle
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_fill(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_fill(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r);
r->d()->context->fill();
- return ctx->thisObject().asReturnedValue();
+ scope.result = callData->thisObject;
}
/*!
@@ -2379,24 +2342,22 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_fill(QV4::CallContext *ctx
Draws a line from the current position to the point (x, y).
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_lineTo(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_lineTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
+ scope.result = callData->thisObject;
- if (ctx->argc() >= 2) {
- qreal x = ctx->args()[0].toNumber();
- qreal y = ctx->args()[1].toNumber();
+ if (callData->argc >= 2) {
+ qreal x = callData->args[0].toNumber();
+ qreal y = callData->args[1].toNumber();
if (!qt_is_finite(x) || !qt_is_finite(y))
- return ctx->thisObject().asReturnedValue();
+ return;
r->d()->context->lineTo(x, y);
}
-
- return ctx->thisObject().asReturnedValue();
}
/*!
@@ -2404,21 +2365,21 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_lineTo(QV4::CallContext *c
Creates a new subpath with the given point.
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_moveTo(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_moveTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->argc() >= 2) {
- qreal x = ctx->args()[0].toNumber();
- qreal y = ctx->args()[1].toNumber();
+ scope.result = callData->thisObject;
+
+ if (callData->argc >= 2) {
+ qreal x = callData->args[0].toNumber();
+ qreal y = callData->args[1].toNumber();
if (!qt_is_finite(x) || !qt_is_finite(y))
- return ctx->thisObject().asReturnedValue();
+ return;
r->d()->context->moveTo(x, y);
}
- return ctx->thisObject().asReturnedValue();
}
/*!
@@ -2428,25 +2389,24 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_moveTo(QV4::CallContext *c
See \l{http://www.w3.org/TR/2dcontext/#dom-context-2d-quadraticcurveto}{W3C 2d context standard for quadraticCurveTo}
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_quadraticCurveTo(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_quadraticCurveTo(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->argc() >= 4) {
- qreal cpx = ctx->args()[0].toNumber();
- qreal cpy = ctx->args()[1].toNumber();
- qreal x = ctx->args()[2].toNumber();
- qreal y = ctx->args()[3].toNumber();
+ scope.result = callData->thisObject;
+
+ if (callData->argc >= 4) {
+ qreal cpx = callData->args[0].toNumber();
+ qreal cpy = callData->args[1].toNumber();
+ qreal x = callData->args[2].toNumber();
+ qreal y = callData->args[3].toNumber();
if (!qt_is_finite(cpx) || !qt_is_finite(cpy) || !qt_is_finite(x) || !qt_is_finite(y))
- return ctx->thisObject().asReturnedValue();
+ return;
r->d()->context->quadraticCurveTo(cpx, cpy, x, y);
}
-
- return ctx->thisObject().asReturnedValue();
}
/*!
@@ -2454,15 +2414,15 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_quadraticCurveTo(QV4::Call
Adds a rectangle at position (\c x, \c y), with the given width \c w and height \c h, as a closed subpath.
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_rect(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_rect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->argc() >= 4)
- r->d()->context->rect(ctx->args()[0].toNumber(), ctx->args()[1].toNumber(), ctx->args()[2].toNumber(), ctx->args()[3].toNumber());
- return ctx->thisObject().asReturnedValue();
+ if (callData->argc >= 4)
+ r->d()->context->rect(callData->args[0].toNumber(), callData->args[1].toNumber(), callData->args[2].toNumber(), callData->args[3].toNumber());
+ scope.result = callData->thisObject;
+
}
/*!
@@ -2471,20 +2431,20 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_rect(QV4::CallContext *ctx
Adds the given rectangle rect with rounded corners to the path. The \c xRadius and \c yRadius arguments specify the radius of the
ellipses defining the corners of the rounded rectangle.
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_roundedRect(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_roundedRect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->argc() >= 6)
- r->d()->context->roundedRect(ctx->args()[0].toNumber()
- , ctx->args()[1].toNumber()
- , ctx->args()[2].toNumber()
- , ctx->args()[3].toNumber()
- , ctx->args()[4].toNumber()
- , ctx->args()[5].toNumber());
- return ctx->thisObject().asReturnedValue();
+ if (callData->argc >= 6)
+ r->d()->context->roundedRect(callData->args[0].toNumber()
+ , callData->args[1].toNumber()
+ , callData->args[2].toNumber()
+ , callData->args[3].toNumber()
+ , callData->args[4].toNumber()
+ , callData->args[5].toNumber());
+ scope.result = callData->thisObject;
+
}
/*!
@@ -2495,17 +2455,17 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_roundedRect(QV4::CallConte
The ellipse is composed of a clockwise curve, starting and finishing at zero degrees (the 3 o'clock position).
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_ellipse(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_ellipse(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->argc() >= 4)
- r->d()->context->ellipse(ctx->args()[0].toNumber(), ctx->args()[1].toNumber(), ctx->args()[2].toNumber(), ctx->args()[3].toNumber());
+ if (callData->argc >= 4)
+ r->d()->context->ellipse(callData->args[0].toNumber(), callData->args[1].toNumber(), callData->args[2].toNumber(), callData->args[3].toNumber());
+
+ scope.result = callData->thisObject;
- return ctx->thisObject().asReturnedValue();
}
/*!
@@ -2514,21 +2474,22 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_ellipse(QV4::CallContext *
Adds the given \c text to the path as a set of closed subpaths created from the current context font supplied.
The subpaths are positioned so that the left end of the text's baseline lies at the point specified by (\c x, \c y).
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_text(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_text(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->argc() >= 3) {
- qreal x = ctx->args()[1].toNumber();
- qreal y = ctx->args()[2].toNumber();
+ scope.result = callData->thisObject;
+
+ if (callData->argc >= 3) {
+ qreal x = callData->args[1].toNumber();
+ qreal y = callData->args[2].toNumber();
if (!qt_is_finite(x) || !qt_is_finite(y))
- return ctx->thisObject().asReturnedValue();
- r->d()->context->text(ctx->args()[0].toQStringNoThrow(), x, y);
+ return;
+ r->d()->context->text(callData->args[0].toQStringNoThrow(), x, y);
}
- return ctx->thisObject().asReturnedValue();
+
}
/*!
@@ -2540,14 +2501,14 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_text(QV4::CallContext *ctx
\sa strokeStyle
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_stroke(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_stroke(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
r->d()->context->stroke();
- return ctx->thisObject().asReturnedValue();
+ scope.result = callData->thisObject;
+
}
/*!
@@ -2557,37 +2518,30 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_stroke(QV4::CallContext *c
\sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-ispointinpath}{W3C 2d context standard for isPointInPath}
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_isPointInPath(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_isPointInPath(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
bool pointInPath = false;
- if (ctx->argc() >= 2)
- pointInPath = r->d()->context->isPointInPath(ctx->args()[0].toNumber(), ctx->args()[1].toNumber());
- return QV4::Primitive::fromBoolean(pointInPath).asReturnedValue();
+ if (callData->argc >= 2)
+ pointInPath = r->d()->context->isPointInPath(callData->args[0].toNumber(), callData->args[1].toNumber());
+ scope.result = QV4::Primitive::fromBoolean(pointInPath).asReturnedValue();
}
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawFocusRing(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_drawFocusRing(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *)
{
- QV4::Scope scope(ctx);
-
- V4THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "Context2D::drawFocusRing is not supported");
+ THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "Context2D::drawFocusRing is not supported");
}
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_setCaretSelectionRect(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_setCaretSelectionRect(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *)
{
- QV4::Scope scope(ctx);
-
- V4THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "Context2D::setCaretSelectionRect is not supported");
+ THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "Context2D::setCaretSelectionRect is not supported");
}
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_caretBlinkRate(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_caretBlinkRate(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *)
{
- QV4::Scope scope(ctx);
-
- V4THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "Context2D::caretBlinkRate is not supported");
+ THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "Context2D::caretBlinkRate is not supported");
}
/*!
@@ -2613,29 +2567,27 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_caretBlinkRate(QV4::CallCo
The default font value is "10px sans-serif".
*/
-QV4::ReturnedValue QQuickJSContext2D::method_get_font(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_get_font(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- return QV4::Encode(scope.engine->newString(r->d()->context->state.font.toString()));
+ RETURN_RESULT(scope.engine->newString(r->d()->context->state.font.toString()));
}
-QV4::ReturnedValue QQuickJSContext2D::method_set_font(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_set_font(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT_SETTER(r)
- QV4::ScopedString s(scope, ctx->argument(0), QV4::ScopedString::Convert);
+ QV4::ScopedString s(scope, callData->argument(0), QV4::ScopedString::Convert);
if (scope.engine->hasException)
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
QFont font = qt_font_from_string(s->toQString(), r->d()->context->state.font);
if (font != r->d()->context->state.font) {
r->d()->context->state.font = font;
}
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
/*!
@@ -2652,37 +2604,35 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_font(QV4::CallContext *ctx)
\endlist
Other values are ignored. The default value is "start".
*/
-QV4::ReturnedValue QQuickJSContext2D::method_get_textAlign(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_get_textAlign(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
switch (r->d()->context->state.textAlign) {
case QQuickContext2D::End:
- return QV4::Encode(scope.engine->newString(QStringLiteral("end")));
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("end")));
case QQuickContext2D::Left:
- return QV4::Encode(scope.engine->newString(QStringLiteral("left")));
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("left")));
case QQuickContext2D::Right:
- return QV4::Encode(scope.engine->newString(QStringLiteral("right")));
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("right")));
case QQuickContext2D::Center:
- return QV4::Encode(scope.engine->newString(QStringLiteral("center")));
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("center")));
case QQuickContext2D::Start:
default:
break;
}
- return QV4::Encode(scope.engine->newString(QStringLiteral("start")));
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("start")));
}
-QV4::ReturnedValue QQuickJSContext2D::method_set_textAlign(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_set_textAlign(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT_SETTER(r)
- QV4::ScopedString s(scope, ctx->argument(0), QV4::ScopedString::Convert);
+ QV4::ScopedString s(scope, callData->argument(0), QV4::ScopedString::Convert);
if (scope.engine->hasException)
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
QString textAlign = s->toQString();
QQuickContext2D::TextAlignType ta;
@@ -2697,12 +2647,12 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_textAlign(QV4::CallContext *ctx
else if (textAlign == QLatin1String("center"))
ta = QQuickContext2D::Center;
else
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
if (ta != r->d()->context->state.textAlign)
r->d()->context->state.textAlign = ta;
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
/*!
@@ -2720,36 +2670,34 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_textAlign(QV4::CallContext *ctx
\endlist
Other values are ignored. The default value is "alphabetic".
*/
-QV4::ReturnedValue QQuickJSContext2D::method_get_textBaseline(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_get_textBaseline(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
switch (r->d()->context->state.textBaseline) {
case QQuickContext2D::Hanging:
- return QV4::Encode(scope.engine->newString(QStringLiteral("hanging")));
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("hanging")));
case QQuickContext2D::Top:
- return QV4::Encode(scope.engine->newString(QStringLiteral("top")));
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("top")));
case QQuickContext2D::Bottom:
- return QV4::Encode(scope.engine->newString(QStringLiteral("bottom")));
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("bottom")));
case QQuickContext2D::Middle:
- return QV4::Encode(scope.engine->newString(QStringLiteral("middle")));
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("middle")));
case QQuickContext2D::Alphabetic:
default:
break;
}
- return QV4::Encode(scope.engine->newString(QStringLiteral("alphabetic")));
+ RETURN_RESULT(scope.engine->newString(QStringLiteral("alphabetic")));
}
-QV4::ReturnedValue QQuickJSContext2D::method_set_textBaseline(QV4::CallContext *ctx)
+void QQuickJSContext2D::method_set_textBaseline(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT_SETTER(r)
- QV4::ScopedString s(scope, ctx->argument(0), QV4::ScopedString::Convert);
+ QV4::ScopedString s(scope, callData->argument(0), QV4::ScopedString::Convert);
if (scope.engine->hasException)
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
QString textBaseline = s->toQString();
QQuickContext2D::TextBaseLineType tb;
@@ -2764,12 +2712,12 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_textBaseline(QV4::CallContext *
else if (textBaseline == QLatin1String("middle"))
tb = QQuickContext2D::Middle;
else
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
if (tb != r->d()->context->state.textBaseline)
r->d()->context->state.textBaseline = tb;
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
/*!
@@ -2780,21 +2728,21 @@ QV4::ReturnedValue QQuickJSContext2D::method_set_textBaseline(QV4::CallContext *
\sa textBaseline
\sa strokeText
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_fillText(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_fillText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->argc() >= 3) {
- qreal x = ctx->args()[1].toNumber();
- qreal y = ctx->args()[2].toNumber();
+ scope.result = callData->thisObject;
+
+ if (callData->argc >= 3) {
+ qreal x = callData->args[1].toNumber();
+ qreal y = callData->args[2].toNumber();
if (!qt_is_finite(x) || !qt_is_finite(y))
- return ctx->thisObject().asReturnedValue();
- QPainterPath textPath = r->d()->context->createTextGlyphs(x, y, ctx->args()[0].toQStringNoThrow());
+ return;
+ QPainterPath textPath = r->d()->context->createTextGlyphs(x, y, callData->args[0].toQStringNoThrow());
r->d()->context->buffer()->fill(textPath);
}
- return ctx->thisObject().asReturnedValue();
}
/*!
\qmlmethod object QtQuick::Context2D::strokeText(text, x, y)
@@ -2804,15 +2752,15 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_fillText(QV4::CallContext
\sa textBaseline
\sa fillText
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_strokeText(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_strokeText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->argc() >= 3)
- r->d()->context->drawText(ctx->args()[0].toQStringNoThrow(), ctx->args()[1].toNumber(), ctx->args()[2].toNumber(), false);
- return ctx->thisObject().asReturnedValue();
+ if (callData->argc >= 3)
+ r->d()->context->drawText(callData->args[0].toQStringNoThrow(), callData->args[1].toNumber(), callData->args[2].toNumber(), false);
+ scope.result = callData->thisObject;
+
}
/*!
@@ -2821,21 +2769,20 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_strokeText(QV4::CallContex
Returns an object with a \c width property, whose value is equivalent to
calling \l {QFontMetrics::width()} with the given \a text in the current font.
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_measureText(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_measureText(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->argc() >= 1) {
+ if (callData->argc >= 1) {
QFontMetrics fm(r->d()->context->state.font);
- uint width = fm.width(ctx->args()[0].toQStringNoThrow());
+ uint width = fm.width(callData->args[0].toQStringNoThrow());
QV4::ScopedObject tm(scope, scope.engine->newObject());
tm->put(QV4::ScopedString(scope, scope.engine->newIdentifier(QStringLiteral("width"))).getPointer(),
QV4::ScopedValue(scope, QV4::Primitive::fromDouble(width)));
- return tm.asReturnedValue();
+ RETURN_RESULT(tm);
}
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
// drawing images
@@ -2897,28 +2844,29 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_measureText(QV4::CallConte
\sa {http://www.w3.org/TR/2dcontext/#dom-context-2d-drawimage}{W3C 2d context standard for drawImage}
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawImage(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_drawImage(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject);
CHECK_CONTEXT(r)
+ scope.result = callData->thisObject;
+
qreal sx, sy, sw, sh, dx, dy, dw, dh;
- if (!ctx->argc())
- return ctx->thisObject().asReturnedValue();
+ if (!callData->argc)
+ return;
//FIXME:This function should be moved to QQuickContext2D::drawImage(...)
if (!r->d()->context->state.invertibleCTM)
- return ctx->thisObject().asReturnedValue();
+ return;
QQmlRefPointer<QQuickCanvasPixmap> pixmap;
- QV4::ScopedValue arg(scope, ctx->args()[0]);
+ QV4::ScopedValue arg(scope, callData->args[0]);
if (arg->isString()) {
QUrl url(arg->toQString());
if (!url.isValid())
- V4THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
+ THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
pixmap = r->d()->context->createPixmap(url);
} else if (arg->isObject()) {
@@ -2931,7 +2879,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawImage(QV4::CallContext
if (!img.isNull())
pixmap.adopt(new QQuickCanvasPixmap(img));
} else {
- V4THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
+ THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
}
} else {
QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, arg);
@@ -2940,44 +2888,44 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawImage(QV4::CallContext
if (pix && !pix->d()->image->isNull()) {
pixmap.adopt(new QQuickCanvasPixmap(*pix->d()->image));
} else {
- V4THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
+ THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
}
} else {
QUrl url(arg->toQStringNoThrow());
if (url.isValid())
pixmap = r->d()->context->createPixmap(url);
else
- V4THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
+ THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
}
}
} else {
- V4THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
+ THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "drawImage(), type mismatch");
}
if (pixmap.isNull() || !pixmap->isValid())
- return ctx->thisObject().asReturnedValue();
-
- if (ctx->argc() >= 9) {
- sx = ctx->args()[1].toNumber();
- sy = ctx->args()[2].toNumber();
- sw = ctx->args()[3].toNumber();
- sh = ctx->args()[4].toNumber();
- dx = ctx->args()[5].toNumber();
- dy = ctx->args()[6].toNumber();
- dw = ctx->args()[7].toNumber();
- dh = ctx->args()[8].toNumber();
- } else if (ctx->argc() >= 5) {
+ return;
+
+ if (callData->argc >= 9) {
+ sx = callData->args[1].toNumber();
+ sy = callData->args[2].toNumber();
+ sw = callData->args[3].toNumber();
+ sh = callData->args[4].toNumber();
+ dx = callData->args[5].toNumber();
+ dy = callData->args[6].toNumber();
+ dw = callData->args[7].toNumber();
+ dh = callData->args[8].toNumber();
+ } else if (callData->argc >= 5) {
sx = 0;
sy = 0;
sw = pixmap->width();
sh = pixmap->height();
- dx = ctx->args()[1].toNumber();
- dy = ctx->args()[2].toNumber();
- dw = ctx->args()[3].toNumber();
- dh = ctx->args()[4].toNumber();
- } else if (ctx->argc() >= 3) {
- dx = ctx->args()[1].toNumber();
- dy = ctx->args()[2].toNumber();
+ dx = callData->args[1].toNumber();
+ dy = callData->args[2].toNumber();
+ dw = callData->args[3].toNumber();
+ dh = callData->args[4].toNumber();
+ } else if (callData->argc >= 3) {
+ dx = callData->args[1].toNumber();
+ dy = callData->args[2].toNumber();
sx = 0;
sy = 0;
sw = pixmap->width();
@@ -2985,7 +2933,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawImage(QV4::CallContext
dw = sw;
dh = sh;
} else {
- return ctx->thisObject().asReturnedValue();
+ return;
}
if (!qt_is_finite(sx)
@@ -2996,7 +2944,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawImage(QV4::CallContext
|| !qt_is_finite(dy)
|| !qt_is_finite(dw)
|| !qt_is_finite(dh))
- return ctx->thisObject().asReturnedValue();
+ return;
if (sx < 0
|| sy < 0
@@ -3005,12 +2953,10 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawImage(QV4::CallContext
|| sx + sw > pixmap->width()
|| sy + sh > pixmap->height()
|| sx + sw < 0 || sy + sh < 0) {
- V4THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "drawImage(), index size error");
+ THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "drawImage(), index size error");
}
r->d()->context->buffer()->drawPixmap(pixmap, QRectF(sx, sy, sw, sh), QRectF(dx, dy, dw, dh));
-
- return ctx->thisObject().asReturnedValue();
}
// pixel manipulation
@@ -3037,45 +2983,40 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawImage(QV4::CallContext
\qmlproperty int QtQuick::CanvasImageData::width
Holds the actual width dimension of the data in the ImageData object, in device pixels.
*/
-QV4::ReturnedValue QQuickJSContext2DImageData::method_get_width(QV4::CallContext *ctx)
+void QQuickJSContext2DImageData::method_get_width(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, callData->thisObject);
if (!imageData)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
QV4::Scoped<QQuickJSContext2DPixelData> r(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>());
- if (!r)
- return QV4::Encode(0);
- return QV4::Encode(r->d()->image->width());
+ int width = r ? r->d()->image->width() : 0;
+ scope.result = QV4::Encode(width);
}
/*!
\qmlproperty int QtQuick::CanvasImageData::height
Holds the actual height dimension of the data in the ImageData object, in device pixels.
*/
-QV4::ReturnedValue QQuickJSContext2DImageData::method_get_height(QV4::CallContext *ctx)
+void QQuickJSContext2DImageData::method_get_height(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, callData->thisObject);
if (!imageData)
- return ctx->engine()->throwTypeError();
+ THROW_TYPE_ERROR();
QV4::Scoped<QQuickJSContext2DPixelData> r(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>());
- if (!r)
- return QV4::Encode(0);
- return QV4::Encode(r->d()->image->height());
+ int height = r ? r->d()->image->height() : 0;
+ scope.result = QV4::Encode(height);
}
/*!
\qmlproperty object QtQuick::CanvasImageData::data
Holds the one-dimensional array containing the data in RGBA order, as integers in the range 0 to 255.
*/
-QV4::ReturnedValue QQuickJSContext2DImageData::method_get_data(QV4::CallContext *ctx)
+void QQuickJSContext2DImageData::method_get_data(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, ctx->thisObject());
+ QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, callData->thisObject);
if (!imageData)
- return ctx->engine()->throwTypeError();
- return imageData->d()->pixelData.asReturnedValue();
+ THROW_TYPE_ERROR();
+ scope.result = imageData->d()->pixelData;
}
/*!
@@ -3096,14 +3037,13 @@ QV4::ReturnedValue QQuickJSContext2DImageData::method_get_data(QV4::CallContext
The length attribute of a CanvasPixelArray object must return this h×w×4 number value.
This property is read only.
*/
-QV4::ReturnedValue QQuickJSContext2DPixelData::proto_get_length(QV4::CallContext *ctx)
+void QQuickJSContext2DPixelData::proto_get_length(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2DPixelData> r(scope, ctx->thisObject().as<QQuickJSContext2DPixelData>());
+ QV4::Scoped<QQuickJSContext2DPixelData> r(scope, callData->thisObject.as<QQuickJSContext2DPixelData>());
if (!r || r->d()->image->isNull())
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
- return QV4::Encode(r->d()->image->width() * r->d()->image->height() * 4);
+ RETURN_RESULT(r->d()->image->width() * r->d()->image->height() * 4);
}
QV4::ReturnedValue QQuickJSContext2DPixelData::getIndexed(const QV4::Managed *m, uint index, bool *hasProperty)
@@ -3192,108 +3132,107 @@ void QQuickJSContext2DPixelData::putIndexed(QV4::Managed *m, uint index, const Q
\sa Canvas::loadImage(), QtQuick::Canvas::unloadImage(),
QtQuick::Canvas::isImageLoaded
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_createImageData(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_createImageData(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (ctx->argc() == 1) {
- QV4::ScopedValue arg0(scope, ctx->args()[0]);
+ if (callData->argc == 1) {
+ QV4::ScopedValue arg0(scope, callData->args[0]);
QV4::Scoped<QQuickJSContext2DImageData> imgData(scope, arg0);
if (!!imgData) {
QV4::Scoped<QQuickJSContext2DPixelData> pa(scope, imgData->d()->pixelData.as<QQuickJSContext2DPixelData>());
if (pa) {
qreal w = pa->d()->image->width();
qreal h = pa->d()->image->height();
- return qt_create_image_data(w, h, scope.engine, QImage());
+ RETURN_RESULT(qt_create_image_data(w, h, scope.engine, QImage()));
}
} else if (arg0->isString()) {
QImage image = r->d()->context->createPixmap(QUrl(arg0->toQStringNoThrow()))->image();
- return qt_create_image_data(image.width(), image.height(), scope.engine, image);
+ RETURN_RESULT(qt_create_image_data(image.width(), image.height(), scope.engine, image));
}
- } else if (ctx->argc() == 2) {
- qreal w = ctx->args()[0].toNumber();
- qreal h = ctx->args()[1].toNumber();
+ } else if (callData->argc == 2) {
+ qreal w = callData->args[0].toNumber();
+ qreal h = callData->args[1].toNumber();
if (!qt_is_finite(w) || !qt_is_finite(h))
- V4THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "createImageData(): invalid arguments");
+ THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "createImageData(): invalid arguments");
if (w > 0 && h > 0)
- return qt_create_image_data(w, h, scope.engine, QImage());
+ RETURN_RESULT(qt_create_image_data(w, h, scope.engine, QImage()));
else
- V4THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "createImageData(): invalid arguments");
+ THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "createImageData(): invalid arguments");
}
- return QV4::Encode::undefined();
+ RETURN_UNDEFINED();
}
/*!
\qmlmethod CanvasImageData QtQuick::Context2D::getImageData(real sx, real sy, real sw, real sh)
Returns an CanvasImageData object containing the image data for the given rectangle of the canvas.
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_getImageData(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_getImageData(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (ctx->argc() >= 4) {
- qreal x = ctx->args()[0].toNumber();
- qreal y = ctx->args()[1].toNumber();
- qreal w = ctx->args()[2].toNumber();
- qreal h = ctx->args()[3].toNumber();
+ if (callData->argc >= 4) {
+ qreal x = callData->args[0].toNumber();
+ qreal y = callData->args[1].toNumber();
+ qreal w = callData->args[2].toNumber();
+ qreal h = callData->args[3].toNumber();
if (!qt_is_finite(x) || !qt_is_finite(y) || !qt_is_finite(w) || !qt_is_finite(h))
- V4THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "getImageData(): Invalid arguments");
+ THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "getImageData(): Invalid arguments");
if (w <= 0 || h <= 0)
- V4THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "getImageData(): Invalid arguments");
+ THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "getImageData(): Invalid arguments");
QImage image = r->d()->context->canvas()->toImage(QRectF(x, y, w, h));
- return qt_create_image_data(w, h, scope.engine, image);
+ RETURN_RESULT(qt_create_image_data(w, h, scope.engine, image));
}
- return QV4::Encode::null();
+ scope.result = QV4::Encode::null();
}
/*!
\qmlmethod object QtQuick::Context2D::putImageData(CanvasImageData imageData, real dx, real dy, real dirtyX, real dirtyY, real dirtyWidth, real dirtyHeight)
Paints the data from the given ImageData object onto the canvas. If a dirty rectangle (\a dirtyX, \a dirtyY, \a dirtyWidth, \a dirtyHeight) is provided, only the pixels from that rectangle are painted.
*/
-QV4::ReturnedValue QQuickJSContext2DPrototype::method_putImageData(QV4::CallContext *ctx)
+void QQuickJSContext2DPrototype::method_putImageData(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickJSContext2D> r(scope, ctx->thisObject().as<QQuickJSContext2D>());
+ QV4::Scoped<QQuickJSContext2D> r(scope, callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (ctx->argc() < 7)
- return QV4::Encode::undefined();
+ if (callData->argc < 7)
+ RETURN_UNDEFINED();
- QV4::ScopedValue arg0(scope, ctx->args()[0]);
+ QV4::ScopedValue arg0(scope, callData->args[0]);
if (!arg0->isObject())
- V4THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "Context2D::putImageData, the image data type mismatch");
+ THROW_DOM(DOMEXCEPTION_TYPE_MISMATCH_ERR, "Context2D::putImageData, the image data type mismatch");
- qreal dx = ctx->args()[1].toNumber();
- qreal dy = ctx->args()[2].toNumber();
+ qreal dx = callData->args[1].toNumber();
+ qreal dy = callData->args[2].toNumber();
qreal w, h, dirtyX, dirtyY, dirtyWidth, dirtyHeight;
if (!qt_is_finite(dx) || !qt_is_finite(dy))
- V4THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "putImageData() : Invalid arguments");
+ THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "putImageData() : Invalid arguments");
+
+ scope.result = callData->thisObject;
QV4::Scoped<QQuickJSContext2DImageData> imageData(scope, arg0);
if (!imageData)
- return ctx->thisObject().asReturnedValue();
+ return;
QV4::Scoped<QQuickJSContext2DPixelData> pixelArray(scope, imageData->d()->pixelData.as<QQuickJSContext2DPixelData>());
if (pixelArray) {
w = pixelArray->d()->image->width();
h = pixelArray->d()->image->height();
- if (ctx->argc() == 7) {
- dirtyX = ctx->args()[3].toNumber();
- dirtyY = ctx->args()[4].toNumber();
- dirtyWidth = ctx->args()[5].toNumber();
- dirtyHeight = ctx->args()[6].toNumber();
+ if (callData->argc == 7) {
+ dirtyX = callData->args[3].toNumber();
+ dirtyY = callData->args[4].toNumber();
+ dirtyWidth = callData->args[5].toNumber();
+ dirtyHeight = callData->args[6].toNumber();
if (!qt_is_finite(dirtyX) || !qt_is_finite(dirtyY) || !qt_is_finite(dirtyWidth) || !qt_is_finite(dirtyHeight))
- V4THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "putImageData() : Invalid arguments");
+ THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "putImageData() : Invalid arguments");
if (dirtyWidth < 0) {
@@ -3325,7 +3264,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_putImageData(QV4::CallCont
}
if (dirtyWidth <=0 || dirtyHeight <= 0)
- return ctx->thisObject().asReturnedValue();
+ return;
} else {
dirtyX = 0;
dirtyY = 0;
@@ -3336,7 +3275,6 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_putImageData(QV4::CallCont
QImage image = pixelArray->d()->image->copy(dirtyX, dirtyY, dirtyWidth, dirtyHeight);
r->d()->context->buffer()->drawImage(image, QRectF(dirtyX, dirtyY, dirtyWidth, dirtyHeight), QRectF(dx, dy, dirtyWidth, dirtyHeight));
}
- return ctx->thisObject().asReturnedValue();
}
/*!
@@ -3359,39 +3297,38 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_putImageData(QV4::CallCont
gradient.addColorStop(0.7, 'rgba(0, 255, 255, 1');
\endcode
*/
-QV4::ReturnedValue QQuickContext2DStyle::gradient_proto_addColorStop(QV4::CallContext *ctx)
+void QQuickContext2DStyle::gradient_proto_addColorStop(const QV4::BuiltinFunction *, QV4::Scope &scope, QV4::CallData *callData)
{
- QV4::Scope scope(ctx);
- QV4::Scoped<QQuickContext2DStyle> style(scope, ctx->thisObject().as<QQuickContext2DStyle>());
+ QV4::Scoped<QQuickContext2DStyle> style(scope, callData->thisObject.as<QQuickContext2DStyle>());
if (!style)
- V4THROW_ERROR("Not a CanvasGradient object");
+ THROW_GENERIC_ERROR("Not a CanvasGradient object");
- if (ctx->argc() == 2) {
+ if (callData->argc == 2) {
if (!style->d()->brush->gradient())
- V4THROW_ERROR("Not a valid CanvasGradient object, can't get the gradient information");
+ THROW_GENERIC_ERROR("Not a valid CanvasGradient object, can't get the gradient information");
QGradient gradient = *(style->d()->brush->gradient());
- qreal pos = ctx->args()[0].toNumber();
+ qreal pos = callData->args[0].toNumber();
QColor color;
- if (ctx->args()[1].as<Object>()) {
- color = scope.engine->toVariant(ctx->args()[1], qMetaTypeId<QColor>()).value<QColor>();
+ if (callData->args[1].as<Object>()) {
+ color = scope.engine->toVariant(callData->args[1], qMetaTypeId<QColor>()).value<QColor>();
} else {
- color = qt_color_from_string(ctx->args()[1]);
+ color = qt_color_from_string(callData->args[1]);
}
if (pos < 0.0 || pos > 1.0 || !qt_is_finite(pos)) {
- V4THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "CanvasGradient: parameter offset out of range");
+ THROW_DOM(DOMEXCEPTION_INDEX_SIZE_ERR, "CanvasGradient: parameter offset out of range");
}
if (color.isValid()) {
gradient.setColorAt(pos, color);
} else {
- V4THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "CanvasGradient: parameter color is not a valid color string");
+ THROW_DOM(DOMEXCEPTION_SYNTAX_ERR, "CanvasGradient: parameter color is not a valid color string");
}
*style->d()->brush = gradient;
}
- return ctx->thisObject().asReturnedValue();
+ scope.result = callData->thisObject;
}
void QQuickContext2D::scale(qreal x, qreal y)
diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp
index 2f66bbebf2..bb23b1fd54 100644
--- a/src/quick/items/qquickmousearea.cpp
+++ b/src/quick/items/qquickmousearea.cpp
@@ -206,6 +206,9 @@ bool QQuickMouseAreaPrivate::propagateHelper(QQuickMouseEvent *ev, QQuickItem *i
the proxied item. When disabled, the mouse area becomes transparent to
mouse events.
+ MouseArea is an invisible Item, but it has a visible property.
+ When set to false, the mouse area becomes transparent to mouse events.
+
The \l pressed read-only property indicates whether or not the user is
holding down a mouse button over the mouse area. This property is often
used in bindings between properties in a user interface. The containsMouse
diff --git a/src/quick/util/qquickimageprovider.cpp b/src/quick/util/qquickimageprovider.cpp
index c4182d9f93..7788635e3e 100644
--- a/src/quick/util/qquickimageprovider.cpp
+++ b/src/quick/util/qquickimageprovider.cpp
@@ -514,9 +514,9 @@ public:
/*!
\class QQuickImageProviderOptions
- \since 5.9
\brief The QQuickImageProviderOptions class provides options for QQuickImageProviderWithOptions image requests.
\inmodule QtQuick
+ \internal
\sa QQuickImageProviderWithOptions
*/
diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp
index 7b369a2d0f..1c6b2afb54 100644
--- a/src/quick/util/qquickpixmapcache.cpp
+++ b/src/quick/util/qquickpixmapcache.cpp
@@ -695,15 +695,6 @@ void QQuickPixmapReader::processJob(QQuickPixmapReply *runningJob, const QUrl &u
QQuickImageProviderWithOptions *providerV2 = provider->d->isProviderWithOptions ? static_cast<QQuickImageProviderWithOptions *>(provider)
: nullptr;
- if (!provider->d->isProviderWithOptions &&
- (providerOptions.autoTransform() != QQuickImageProviderOptions::UsePluginDefaultTransform
- || providerOptions.preserveAspectRatioCrop()
- || providerOptions.preserveAspectRatioFit())
- )
- {
- qWarning() << "Trying to pass extra request flags to provider but it is not a QQuickImageProviderWithOptions";
- }
-
switch (imageType) {
case QQuickImageProvider::Invalid:
{
diff --git a/src/quick/util/qquickpixmapcache_p.h b/src/quick/util/qquickpixmapcache_p.h
index eea6a7a454..f7cdfa7d07 100644
--- a/src/quick/util/qquickpixmapcache_p.h
+++ b/src/quick/util/qquickpixmapcache_p.h
@@ -91,7 +91,7 @@ public:
};
// ### Qt 6: Make public moving to qquickimageprovider.h
-class Q_QUICK_EXPORT QQuickImageProviderOptions
+class Q_QUICK_PRIVATE_EXPORT QQuickImageProviderOptions
{
public:
enum AutoTransform {
@@ -188,7 +188,7 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(QQuickPixmap::Options)
// This class will disappear with Qt6 and will just be the regular QQuickImageProvider
// ### Qt 6: Remove this class and fold it with QQuickImageProvider
-class Q_QUICK_EXPORT QQuickImageProviderWithOptions : public QQuickAsyncImageProvider
+class Q_QUICK_PRIVATE_EXPORT QQuickImageProviderWithOptions : public QQuickAsyncImageProvider
{
public:
QQuickImageProviderWithOptions(ImageType type, Flags flags = Flags());