#include "qv8profilerservice_p.h"
#include "qqmldebugservice_p_p.h"
#include <private/qv8profiler_p.h>
-#include <private/qv8_p.h>
#include <QtCore/QHash>
#include <QtCore/QMutex>
if (d->m_ongoing.contains(title))
return;
- v8::Handle<v8::String> v8title = v8::String::New(reinterpret_cast<const uint16_t*>(title.data()), title.size());
+// v8::Handle<v8::String> v8title = v8::String::New(reinterpret_cast<const uint16_t*>(title.data()), title.size());
// ### FIXME: v4
// v8::CpuProfiler::StartProfiling(v8title);
#include "qqml.h"
#include "qqmlerror.h"
-#include <private/qv8_p.h>
#include "qqmlinstruction_p.h"
#include "qqmlscript_p.h"
#include "qqmlengine_p.h"
#include <private/qflagpointer_p.h>
#include <private/qqmlguard_p.h>
-#include <private/qv8_p.h>
-
QT_BEGIN_NAMESPACE
#include <private/qtqmlglobal_p.h>
#include <private/qobject_p.h>
-#include <private/qv8_p.h>
#include <private/qv4value_p.h>
// We mean it.
//
-#include <private/qv8_p.h>
#include <QtCore/qglobal.h>
#include <QtQml/qqmlerror.h>
#include <private/qqmlengine_p.h>
#include <QtQml/qqmlengine.h>
#include <QtQml/qqmlfile.h>
-#include <private/qv8_p.h>
#include <private/qhashedstring_p.h>
#include <private/qqmlscript_p.h>
#include <private/qqmlimport_p.h>
#include <QtCore/qcoreapplication.h>
#include <QtCore/qtypeinfo.h>
-#include <private/qv8_p.h>
#include <private/qqmlengine_p.h>
#include <private/qfinitestack_p.h>
#include <private/qv8engine_p.h>
#include <private/qflagpointer_p.h>
-#include <private/qv8_p.h>
-
#include <private/qv4value_p.h>
QT_BEGIN_NAMESPACE
#include <private/qqmlcontext_p.h>
#include <private/qqmlguard_p.h>
-#include <private/qv8_p.h>
-
#include <private/qv4value_p.h>
+#include <private/qv4context_p.h>
QT_BEGIN_NAMESPACE
+++ /dev/null
-/****************************************************************************
-**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the V4VM 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 Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qv4v8_p.h"
-
-#include "qv4engine_p.h"
-#include "qv4runtime_p.h"
-#include "qv4mm_p.h"
-#include "qv4managed_p.h"
-#include "qv4functionobject_p.h"
-#include "qv4value_p.h"
-#include "qv4isel_masm_p.h"
-#include "qv4globalobject_p.h"
-#include "qv4regexpobject_p.h"
-#include "qv4dateobject_p.h"
-#include "qv4numberobject_p.h"
-#include "qv4booleanobject_p.h"
-#include "qv4stringobject_p.h"
-#include "qv4objectproto_p.h"
-#include "qv4script_p.h"
-#include <QThreadStorage>
-
-using namespace QQmlJS;
-using namespace QV4;
-
-namespace v8 {
-
-#define currentEngine() Isolate::GetCurrent()->GetEngine()
-
-#define Q_D(obj) QV4::Value *d = reinterpret_cast<QV4::Value*>(obj)
-
-#define ValuePtr(obj) reinterpret_cast<QV4::Value*>(obj)
-#define ConstValuePtr(obj) reinterpret_cast<const QV4::Value*>(obj)
-
-void *gcProtect(void *handle)
-{
- Q_D(handle);
- if (QV4::Managed *m = d->asManaged()) {
- currentEngine()->memoryManager->protect(m);
- return currentEngine()->memoryManager;
- }
-}
-
-void gcProtect(void *memoryManager, void *handle)
-{
- Q_D(handle);
- if (QV4::Managed *m = d->asManaged())
- if (memoryManager)
- static_cast<QV4::MemoryManager *>(memoryManager)->protect(m);
-}
-
-void gcUnprotect(void *memoryManager, void *handle)
-{
- Q_D(handle);
- if (QV4::Managed *m = d->asManaged())
- if (memoryManager)
- static_cast<QV4::MemoryManager *>(memoryManager)->unprotect(m);
-}
-
-quint64 qv8_get_value(const QV4::Value &v)
-{
- return v.val;
-}
-
-struct V8AccessorGetter: FunctionObject {
- AccessorGetter getter;
- QV4::PersistentValue data;
- QV4::PersistentValue name;
-
- V8AccessorGetter(ExecutionContext *scope, const Handle<String> &name, const AccessorGetter &getter, Handle<Value> data)
- : FunctionObject(scope)
- {
- vtbl = &static_vtbl;
- this->getter = getter;
- this->data = data->v4Value();
- this->name = name->v4Value();
- }
-
- using Object::construct;
-
- static QV4::Value call(Managed *that, ExecutionContext *context, const QV4::Value &thisObject, QV4::Value *args, int argc)
- {
- V8AccessorGetter *getter = static_cast<V8AccessorGetter*>(that);
- AccessorInfo info(thisObject, getter->data.value());
- QV4::Value result = QV4::Value::undefinedValue();
- return getter->getter(getter->name.value(), info)->v4Value();
- }
-
-protected:
- static const ManagedVTable static_vtbl;
-};
-
-DEFINE_MANAGED_VTABLE(V8AccessorGetter);
-
-struct V8AccessorSetter: FunctionObject {
- AccessorSetter setter;
- QV4::PersistentValue data;
- QV4::PersistentValue name;
-
- V8AccessorSetter(ExecutionContext *scope, const Handle<String> &name, const AccessorSetter &setter, Handle<Value> data)
- : FunctionObject(scope)
- {
- vtbl = &static_vtbl;
- this->setter = setter;
- this->data = data->v4Value();
- this->name = name->v4Value();
- }
-
- using Object::construct;
-
- static QV4::Value call(Managed *that, ExecutionContext *context, const QV4::Value &thisObject, QV4::Value *args, int argc)
- {
- if (!argc)
- return QV4::Value::undefinedValue();
- V8AccessorSetter *setter = static_cast<V8AccessorSetter*>(that);
- AccessorInfo info(thisObject, setter->data.value());
- setter->setter(setter->name.value(), args[0], info);
- return QV4::Value::undefinedValue();
- }
-
-protected:
- static const ManagedVTable static_vtbl;
-};
-
-DEFINE_MANAGED_VTABLE(V8AccessorSetter);
-
-
-
-bool Value::IsUndefined() const
-{
- return ConstValuePtr(this)->isUndefined();
-}
-
-bool Value::IsNull() const {
- return ConstValuePtr(this)->isNull();
-}
-
-bool Value::IsTrue() const
-{
- return ConstValuePtr(this)->isBoolean() && ConstValuePtr(this)->booleanValue();
-}
-
-bool Value::IsFalse() const
-{
- return !IsTrue();
-}
-
-bool Value::IsString() const
-{
- return ConstValuePtr(this)->isString();
-}
-
-bool Value::IsFunction() const
-{
- return ConstValuePtr(this)->asFunctionObject();
-}
-
-bool Value::IsArray() const
-{
- return ConstValuePtr(this)->asArrayObject();
-}
-
-bool Value::IsObject() const
-{
- return ConstValuePtr(this)->isObject();
-}
-
-bool Value::IsBoolean() const
-{
- return ConstValuePtr(this)->isBoolean();
-}
-
-bool Value::IsNumber() const
-{
- return ConstValuePtr(this)->isNumber();
-}
-
-bool Value::IsExternal() const
-{
- Q_UNIMPLEMENTED();
- Q_UNREACHABLE();
-}
-
-bool Value::IsInt32() const
-{
- return ConstValuePtr(this)->isInteger();
-}
-
-bool Value::IsUint32() const
-{
- Q_UNIMPLEMENTED();
- Q_UNREACHABLE();
-}
-
-bool Value::IsDate() const
-{
- return ConstValuePtr(this)->asDateObject();
-}
-
-bool Value::IsBooleanObject() const
-{
- return ConstValuePtr(this)->asBooleanObject();
-}
-
-bool Value::IsNumberObject() const
-{
- return ConstValuePtr(this)->asNumberObject();
-}
-
-bool Value::IsStringObject() const
-{
- return ConstValuePtr(this)->asStringObject();
-}
-
-bool Value::IsRegExp() const
-{
- return ConstValuePtr(this)->as<RegExpObject>();
-}
-
-bool Value::IsError() const
-{
- return ConstValuePtr(this)->asErrorObject();
-}
-
-Handle<String> Value::ToString() const
-{
- return QV4::Value::fromString(ConstValuePtr(this)->toString(currentEngine()->current));
-}
-
-Handle<Object> Value::ToObject() const
-{
- return QV4::Value::fromObject(ConstValuePtr(this)->toObject(currentEngine()->current));
-}
-
-bool Value::BooleanValue() const
-{
- return ConstValuePtr(this)->toBoolean();
-}
-
-double Value::NumberValue() const
-{
- return ConstValuePtr(this)->asDouble();
-}
-
-int64_t Value::IntegerValue() const
-{
- return (int64_t)ConstValuePtr(this)->toInteger();
-}
-
-uint32_t Value::Uint32Value() const
-{
- return ConstValuePtr(this)->toUInt32();
-}
-
-int32_t Value::Int32Value() const
-{
- return ConstValuePtr(this)->toInt32();
-}
-
-bool Value::Equals(Handle<Value> that) const
-{
- return __qmljs_equal(*ConstValuePtr(this), *ConstValuePtr(&that));
-}
-
-bool Value::StrictEquals(Handle<Value> that) const
-{
- return __qmljs_strict_equal(*ConstValuePtr(this), *ConstValuePtr(&that));
-}
-
-QV4::Value Value::v4Value() const
-{
- return *ConstValuePtr(this);
-}
-
-Handle<Value> Value::fromV4Value(const QV4::Value &v4Value)
-{
- Handle<Value> res;
- res.val = v4Value.val;
- return res;
-}
-
-
-String::ExternalStringResource *String::GetExternalStringResource() const
-{
- Q_UNIMPLEMENTED();
- Q_UNREACHABLE();
-}
-
-String *String::Cast(v8::Value *obj)
-{
- return static_cast<String *>(obj);
-}
-
-
-Handle<String> String::New(const char *data, int length)
-{
- QV4::Value v = QV4::Value::fromString(currentEngine()->current, QString::fromLatin1(data, length));
- return v;
-}
-
-Handle<String> String::New(const uint16_t *data, int length)
-{
- QV4::Value v = QV4::Value::fromString(currentEngine()->current, QString((const QChar *)data, length));
- return v;
-}
-
-Handle<String> String::New(QV4::String *s)
-{
- return QV4::Value::fromString(s);
-}
-
-Handle<String> String::NewExternal(String::ExternalStringResource *resource)
-{
- Q_UNIMPLEMENTED();
- Q_UNREACHABLE();
-}
-
-QString String::asQString() const
-{
- return asV4String()->toQString();
-}
-
-QV4::String *String::asV4String() const
-{
- const QV4::Value *v = ConstValuePtr(this);
- ASSERT(v->isString());
- return v->stringValue();
-}
-
-
-struct ExternalResourceWrapper : public QV4::Object::ExternalResource
-{
- ExternalResourceWrapper(v8::Object::ExternalResource *wrapped)
- {
- this->wrapped = wrapped;
- }
-
- virtual ~ExternalResourceWrapper()
- {
- wrapped->Dispose();
- }
-
- v8::Object::ExternalResource *wrapped;
-};
-
-
-bool Object::Set(Handle<Value> key, Handle<Value> value, PropertyAttribute attribs)
-{
- QV4::Object *o = ConstValuePtr(this)->asObject();
- assert(o);
- QV4::ExecutionContext *ctx = currentEngine()->current;
- bool result = true;
- try {
- o->put(ctx, ValuePtr(&key)->toString(ctx), *ValuePtr(&value));
- // ### attribs
- } catch (QV4::Exception &e) {
- e.accept(ctx);
- result = false;
- }
- return result;
-}
-
-bool Object::Set(uint32_t index, Handle<Value> value)
-{
- QV4::Object *o = ConstValuePtr(this)->asObject();
- assert(o);
- QV4::ExecutionContext *ctx = currentEngine()->current;
- bool result = true;
- try {
- o->putIndexed(ctx, index, *ValuePtr(&value));
- // ### attribs
- } catch (QV4::Exception &e) {
- e.accept(ctx);
- result = false;
- }
- return result;
-}
-
-Handle<Value> Object::Get(Handle<Value> key)
-{
- QV4::Object *o = ConstValuePtr(this)->asObject();
- assert(o);
- QV4::ExecutionContext *ctx = currentEngine()->current;
- QV4::Value prop = QV4::Value::undefinedValue();
- try {
- prop = o->get(ctx, ValuePtr(&key)->toString(ctx));
- } catch (QV4::Exception &e) {
- e.accept(ctx);
- return Handle<Value>();
- }
- return prop;
-}
-
-Handle<Value> Object::Get(uint32_t key)
-{
- QV4::Object *o = ConstValuePtr(this)->asObject();
- assert(o);
- QV4::ExecutionContext *ctx = currentEngine()->current;
- QV4::Value prop = QV4::Value::undefinedValue();
- try {
- prop = o->getIndexed(ctx, key);
- } catch (QV4::Exception &e) {
- e.accept(ctx);
- return Handle<Value>();
- }
- return prop;
-}
-
-bool Object::Has(Handle<String> key)
-{
- QV4::Object *o = ConstValuePtr(this)->asObject();
- assert(o);
- return o->__hasProperty__(ValuePtr(&key)->asString());
-}
-
-bool Object::Delete(Handle<String> key)
-{
- QV4::Object *o = ConstValuePtr(this)->asObject();
- assert(o);
- bool result = false;
- ExecutionContext *ctx = currentEngine()->current;
- try {
- result = o->deleteProperty(ctx, ValuePtr(&key)->asString());
- } catch (QV4::Exception &e) {
- e.accept(ctx);
- }
- return result;
-}
-
-bool Object::Has(uint32_t index)
-{
- QV4::Object *o = ConstValuePtr(this)->asObject();
- if (!o)
- return false;
- return o->__hasProperty__(index);
-}
-
-bool Object::Delete(uint32_t index)
-{
- QV4::Object *o = ConstValuePtr(this)->asObject();
- assert(o);
- ExecutionContext *ctx = currentEngine()->current;
- bool result = false;
- try {
- result = o->deleteIndexedProperty(ctx, index);
- } catch (QV4::Exception &e) {
- e.accept(ctx);
- }
- return result;
-}
-
-bool Object::SetAccessor(Handle<String> name, AccessorGetter getter, AccessorSetter setter, Handle<Value> data, AccessControl settings, PropertyAttribute attribute)
-{
- QV4::ExecutionEngine *engine = currentEngine();
-
- QV4::FunctionObject *wrappedGetter = 0;
- if (getter) {
- wrappedGetter = new (engine->memoryManager) V8AccessorGetter(engine->rootContext, name, getter, data);
- }
- QV4::FunctionObject *wrappedSetter = 0;
- if (setter) {
- wrappedSetter = new (engine->memoryManager) V8AccessorSetter(engine->rootContext, name, setter, data);
- }
-
- QV4::Object *o = ConstValuePtr(this)->asObject();
- assert(o);
- PropertyAttributes attrs = Attr_Accessor;
- attrs.setConfigurable(!(attribute & DontDelete));
- attrs.setEnumerable(!(attribute & DontEnum));
- QV4::Property *pd = o->insertMember(name->asV4String(), attrs);
- pd->setGetter(wrappedGetter);
- pd->setSetter(wrappedSetter);
- return true;
-}
-
-Handle<Array> Object::GetPropertyNames()
-{
- QV4::Object *o = ConstValuePtr(this)->asObject();
- assert(o);
-
- QV4::ArrayObject *array = currentEngine()->newArrayObject();
- ObjectIterator it(o, ObjectIterator::WithProtoChain|ObjectIterator::EnumerableOnly);
- while (1) {
- QV4::Value name = it.nextPropertyNameAsString();
- if (name.isNull())
- break;
- array->push_back(name);
- }
- return QV4::Value::fromObject(array);
-}
-
-Handle<Array> Object::GetOwnPropertyNames()
-{
- QV4::Object *o = ConstValuePtr(this)->asObject();
- assert(o);
- QV4::Value arg = QV4::Value::fromObject(o);
- ArrayObject *array = currentEngine()->newArrayObject();
- ObjectIterator it(o, ObjectIterator::EnumerableOnly);
- while (1) {
- QV4::Value name = it.nextPropertyNameAsString();
- if (name.isNull())
- break;
- array->push_back(name);
- }
- return QV4::Value::fromObject(array);
-}
-
-Handle<Value> Object::GetPrototype()
-{
- Handle<Value> result;
- QV4::Object *o = ConstValuePtr(this)->asObject();
- if (!o)
- return Handle<Value>();
- return QV4::Value::fromObject(o->prototype);
-}
-
-bool Object::SetPrototype(Handle<Value> prototype)
-{
- QV4::Object *p = ConstValuePtr(&prototype)->asObject();
- if (!p)
- return false;
- QV4::Object *o = ConstValuePtr(this)->asObject();
- if (!o)
- return false;
-
- o->prototype = p;
- return true;
-}
-
-Handle<Value> Object::GetInternalField(int index)
-{
- QV4::Object *o = ConstValuePtr(this)->asObject();
- if (!o)
- return Handle<Value>();
- QString internalFieldName = QStringLiteral("_internalfield_");
- internalFieldName += QString::number(index);
- return o->get(o->engine()->newString(internalFieldName));
-}
-
-void Object::SetInternalField(int index, Handle<Value> value)
-{
- QV4::Object *o = ConstValuePtr(this)->asObject();
- if (!o)
- return;
- QString internalFieldName = QStringLiteral("_internalfield_");
- internalFieldName += QString::number(index);
- o->put(o->engine()->newString(internalFieldName), value->v4Value());
-}
-
-void Object::SetExternalResource(Object::ExternalResource *resource)
-{
- QV4::Object *o = ConstValuePtr(this)->asObject();
- if (!o)
- return;
- o->externalResource = new ExternalResourceWrapper(resource);
-}
-
-Object::ExternalResource *Object::GetExternalResource()
-{
- QV4::Object *o = ConstValuePtr(this)->asObject();
- if (!o || !o->externalResource)
- return 0;
- return static_cast<ExternalResourceWrapper*>(o->externalResource)->wrapped;
-}
-
-bool Object::HasOwnProperty(Handle<String> key)
-{
- QV4::Object *o = ConstValuePtr(this)->asObject();
- assert(o);
- QV4::ExecutionContext *ctx = currentEngine()->current;
- return o->__getOwnProperty__(ValuePtr(&key)->toString(ctx));
-}
-
-int Object::GetIdentityHash()
-{
- return (quintptr)ConstValuePtr(this)->asObject() >> 2;
-}
-
-Handle<Object> Object::Clone()
-{
- Q_UNIMPLEMENTED();
- Q_UNREACHABLE();
-}
-
-bool Object::IsCallable()
-{
- return ConstValuePtr(this)->asFunctionObject();
-}
-
-Handle<Value> Object::CallAsFunction(Handle<Object> recv, int argc, Handle<Value> argv[])
-{
- QV4::FunctionObject *f = ConstValuePtr(this)->asFunctionObject();
- if (!f)
- return Handle<Value>();
- ExecutionContext *context = currentEngine()->current;
- try {
- QV4::Value retval = f->call(context, recv->v4Value(),
- reinterpret_cast<QV4::Value*>(argv),
- argc);
- return retval;
- } catch (QV4::Exception &e) {
- e.accept(context);
- }
- return Handle<Object>();
-}
-
-Handle<Value> Object::CallAsConstructor(int argc, Handle<Value> argv[])
-{
- QV4::FunctionObject *f = ConstValuePtr(this)->asFunctionObject();
- if (!f)
- return Handle<Value>();
- ExecutionContext *context = currentEngine()->current;
- try {
- QV4::Value retval = f->construct(context,
- reinterpret_cast<QV4::Value*>(argv),
- argc);
- return retval;
- } catch (QV4::Exception &e) {
- e.accept(context);
- }
- return Handle<Object>();
-}
-
-Handle<Object> Object::New()
-{
- QV4::Object *o = currentEngine()->newObject();
- return QV4::Value::fromObject(o);
-}
-
-Object *Object::Cast(Value *obj)
-{
- return static_cast<Object *>(obj);
-}
-
-
-uint32_t Array::Length() const
-{
- QV4::ArrayObject *a = ConstValuePtr(this)->asArrayObject();
- if (!a)
- return 0;
- return a->arrayLength();
-}
-
-Handle<Array> Array::New(int length)
-{
- if (length < 0)
- length = 0;
- QV4::ArrayObject *a = currentEngine()->newArrayObject();
- if (length < 0x1000)
- a->arrayReserve(length);
-
- return QV4::Value::fromObject(a);
-}
-
-Array *Array::Cast(Value *obj)
-{
- return static_cast<Array *>(obj);
-}
-
-
-Handle<Object> Function::NewInstance() const
-{
- QV4::FunctionObject *f = ConstValuePtr(this)->asFunctionObject();
- assert(f);
- QV4::ExecutionContext *context = currentEngine()->current;
- QV4::Value result = QV4::Value::undefinedValue();
- try {
- result = f->construct(context, 0, 0);
- } catch (QV4::Exception &e) {
- e.accept(context);
- return Handle<Object>();
- }
- return result;
-}
-
-Handle<Object> Function::NewInstance(int argc, Handle<Value> argv[]) const
-{
- QV4::FunctionObject *f = ConstValuePtr(this)->asFunctionObject();
- assert(f);
- QV4::ExecutionContext *context = currentEngine()->current;
- QV4::Value result = QV4::Value::undefinedValue();
- try {
- result = f->construct(context, reinterpret_cast<QV4::Value*>(argv), argc);
- } catch (QV4::Exception &e) {
- e.accept(context);
- return Handle<Object>();
- }
- return result;
-}
-
-Handle<Value> Function::Call(Handle<Object> thisObj, int argc, Handle<Value> argv[])
-{
- QV4::FunctionObject *f = ConstValuePtr(this)->asFunctionObject();
- if (!f)
- return Handle<Value>();
- QV4::ExecutionContext *context = currentEngine()->current;
- QV4::Value result = QV4::Value::undefinedValue();
- try {
- result = f->call(context, *ConstValuePtr(&thisObj),
- reinterpret_cast<QV4::Value*>(argv), argc);
- } catch (QV4::Exception &e) {
- e.accept(context);
- return Handle<Value>();
- }
- return result;
-}
-
-Handle<Value> Function::GetName() const
-{
- QV4::FunctionObject *f = ConstValuePtr(this)->asFunctionObject();
- if (!f)
- return Handle<Value>();
- return Value::fromV4Value(QV4::Value::fromString(f->name));
-}
-
-Function *Function::Cast(Value *obj)
-{
- return static_cast<Function *>(obj);
-}
-
-
-struct VoidStarWrapper : public QV4::Object::ExternalResource
-{
- void *data;
-};
-
-Handle<Value> External::Wrap(void *data)
-{
- return New(data);
-}
-
-void *External::Unwrap(Handle<v8::Value> obj)
-{
- return obj.As<External>()->Value();
-}
-
-Handle<External> External::New(void *value)
-{
- QV4::Object *o = currentEngine()->newObject();
- VoidStarWrapper *wrapper = new VoidStarWrapper;
- wrapper->data = value;
- o->externalResource = wrapper;
- return QV4::Value::fromObject(o);
-}
-
-External *External::Cast(v8::Value *obj)
-{
- return static_cast<External *>(obj);
-}
-
-void *External::Value() const
-{
- QV4::Object *o = ConstValuePtr(this)->asObject();
- if (!o || !o->externalResource)
- return 0;
- return static_cast<VoidStarWrapper*>(o->externalResource)->data;
-}
-
-
-void Template::Set(Handle<String> name, Handle<Value> value, PropertyAttribute attributes)
-{
- Property p;
- p.name = name->v4Value();
- p.value = value->v4Value();
- p.attributes = attributes;
- m_properties << p;
-}
-
-void Template::Set(const char *name, Handle<Value> value)
-{
- Set(String::New(name), value);
-}
-
-
-Arguments::Arguments(const QV4::Value *args, int argc, const QV4::Value &thisObject, bool isConstructor, const Handle<Value> &data)
-{
- for (int i = 0; i < argc; ++i)
- m_args << args[i];
- m_thisObject = thisObject;
- m_isConstructor = isConstructor;
- m_data = data->v4Value();
-}
-
-int Arguments::Length() const
-{
- return m_args.size();
-}
-
-Handle<Value> Arguments::operator [](int i) const
-{
- return m_args.at(i).value();
-}
-
-Handle<Object> Arguments::This() const
-{
- return m_thisObject.value();
-}
-
-QV4::Value Arguments::ThisV4() const
-{
- return m_thisObject;
-}
-
-Handle<Object> Arguments::Holder() const
-{
- // ### FIXME.
- return m_thisObject.value();
-}
-
-bool Arguments::IsConstructCall() const
-{
- return m_isConstructor;
-}
-
-Handle<Value> Arguments::Data() const
-{
- return m_data.value();
-}
-
-Isolate *Arguments::GetIsolate() const
-{
- return Isolate::GetCurrent();
-}
-
-
-AccessorInfo::AccessorInfo(const QV4::Value &thisObject, const Handle<Value> &data)
-{
- m_this = thisObject;
- m_data = data->v4Value();
-}
-
-Isolate *AccessorInfo::GetIsolate() const
-{
- return Isolate::GetCurrent();
-}
-
-Handle<Value> AccessorInfo::Data() const
-{
- return m_data.value();
-}
-
-Handle<Object> AccessorInfo::This() const
-{
- return m_this.value();
-}
-
-Handle<Object> AccessorInfo::Holder() const
-{
- // ### FIXME
- return m_this.value();
-}
-
-template <typename BaseClass>
-class V4V8Object : public BaseClass
-{
-public:
- V4V8Object(QV4::ExecutionEngine *engine, ObjectTemplate *tmpl)
- : BaseClass(engine->rootContext)
- {
- this->vtbl = &static_vtbl;
- m_template = tmpl;
- if (!m_template)
- m_template = ObjectTemplate::New().get();
-
- foreach (const ObjectTemplate::Accessor &acc, m_template->m_accessors) {
- PropertyAttributes attrs = Attr_Accessor;
- attrs.setConfigurable(!(acc.attribute & DontDelete));
- attrs.setEnumerable(!(acc.attribute & DontEnum));
- QV4::Property *pd = this->insertMember(acc.name.value().asString(), attrs);
- *pd = QV4::Property::fromAccessor(acc.getter.value().asFunctionObject(),
- acc.setter.value().asFunctionObject());
- }
-
- initProperties(m_template.data());
- }
-
- void initProperties(Template *tmpl)
- {
- foreach (const Template::Property &p, tmpl->m_properties) {
- PropertyAttributes attrs = Attr_Data;
- attrs.setConfigurable(!(p.attributes & DontDelete));
- attrs.setEnumerable(!(p.attributes & DontEnum));
- attrs.setWritable(!(p.attributes & ReadOnly));
- QV4::Property *pd = this->insertMember(p.name.value().asString(), attrs);
- *pd = QV4::Property::fromValue(p.value);
- }
- }
-
- QExplicitlySharedDataPointer<ObjectTemplate> m_template;
-
-protected:
- AccessorInfo namedAccessorInfo() const
- {
- // ### thisObject?
- return AccessorInfo(QV4::Value::fromObject(static_cast<QV4::Object*>(const_cast<V4V8Object<BaseClass>*>(this))), m_template->m_namedPropertyData.value());
- }
- AccessorInfo fallbackAccessorInfo() const
- {
- // ### thisObject?
- return AccessorInfo(QV4::Value::fromObject(static_cast<QV4::Object*>(const_cast<V4V8Object<BaseClass>*>(this))), m_template->m_fallbackPropertyData.value());
- }
- AccessorInfo indexedAccessorInfo() const
- {
- // ### thisObject?
- return AccessorInfo(QV4::Value::fromObject(static_cast<QV4::Object*>(const_cast<V4V8Object<BaseClass>*>(this))), m_template->m_namedPropertyData.value());
- }
-
- static const ManagedVTable static_vtbl;
-
- static QV4::Value get(QV4::Managed *m, ExecutionContext *ctx, QV4::String *name, bool *hasProperty)
- {
- V4V8Object *that = static_cast<V4V8Object*>(m);
- if (that->m_template->m_namedPropertyGetter) {
- Handle<Value> result = that->m_template->m_namedPropertyGetter(String::New(name), that->namedAccessorInfo());
- if (!result.IsEmpty()) {
- if (hasProperty)
- *hasProperty = true;
- return result->v4Value();
- }
- }
-
- bool hasProp = false;
- QV4::Value result = BaseClass::get(m, ctx, name, &hasProp);
-
- if (!hasProp && that->m_template->m_fallbackPropertyGetter) {
- Handle<Value> fallbackResult = that->m_template->m_fallbackPropertyGetter(String::New(name), that->fallbackAccessorInfo());
- if (!fallbackResult.IsEmpty()) {
- if (hasProperty)
- *hasProperty = true;
- return fallbackResult->v4Value();
- }
- }
-
- if (hasProperty)
- *hasProperty = hasProp;
- return result;
- }
-
- static QV4::Value getIndexed(QV4::Managed *m, ExecutionContext *ctx, uint index, bool *hasProperty)
- {
- V4V8Object *that = static_cast<V4V8Object*>(m);
- if (that->m_template->m_indexedPropertyGetter) {
- Handle<Value> result = that->m_template->m_indexedPropertyGetter(index, that->indexedAccessorInfo());
- if (!result.IsEmpty()) {
- if (hasProperty)
- *hasProperty = true;
- return result->v4Value();
- }
- }
- return BaseClass::getIndexed(m, ctx, index, hasProperty);
- }
-
- static void put(QV4::Managed *m, ExecutionContext *ctx, QV4::String *name, const QV4::Value &value)
- {
- Handle<Value> v8Value = value;
- V4V8Object *that = static_cast<V4V8Object*>(m);
- if (that->m_template->m_namedPropertySetter) {
- Handle<Value> result = that->m_template->m_namedPropertySetter(String::New(name), v8Value, that->namedAccessorInfo());
- if (!result.IsEmpty())
- return;
- }
- PropertyAttributes attrs;
- Property *pd = that->__getOwnProperty__(name, &attrs);
- if (pd) {
- that->putValue(ctx, pd, attrs, value);
- return;
- }
- if (that->m_template->m_fallbackPropertySetter) {
- Handle<Value> v = that->m_template->m_fallbackPropertySetter(String::New(name), v8Value, that->fallbackAccessorInfo());
- if (!v.IsEmpty())
- return;
- }
-
- BaseClass::put(m, ctx, name, value);
- }
-
- static void putIndexed(QV4::Managed *m, ExecutionContext *ctx, uint index, const QV4::Value &value)
- {
- V4V8Object *that = static_cast<V4V8Object*>(m);
- if (that->m_template->m_indexedPropertySetter) {
- Handle<Value> result = that->m_template->m_indexedPropertySetter(index, value, that->indexedAccessorInfo());
- if (!result.IsEmpty())
- return;
- }
- BaseClass::putIndexed(m, ctx, index, value);
- }
-
- static void getLookup(QV4::Managed *m, ExecutionContext *ctx, Lookup *l, QV4::Value *result)
- {
- *result = get(m, ctx, l->name, 0);
- }
-
- static void setLookup(QV4::Managed *m, ExecutionContext *ctx, Lookup *l, const QV4::Value &value)
- {
- put(m, ctx, l->name, value);
- }
-
- static PropertyAttributes propertyAttributesToFlags(const Handle<Value> &attr)
- {
- PropertyAttributes flags;
- int intAttr = attr->v4Value().toInt32();
- flags.setWritable(!(intAttr & ReadOnly));
- flags.setEnumerable(!(intAttr & DontEnum));
- flags.setConfigurable(!(intAttr & DontDelete));
- return flags;
- }
-
- static PropertyAttributes query(const QV4::Managed *m, QV4::String *name)
- {
- const V4V8Object *that = static_cast<const V4V8Object*>(m);
- if (that->m_template->m_namedPropertyQuery) {
- Handle<Value> result = that->m_template->m_namedPropertyQuery(String::New(name), that->namedAccessorInfo());
- if (!result.IsEmpty())
- return propertyAttributesToFlags(result);
- }
- PropertyAttributes flags = BaseClass::query(m, name);
- if (flags.type() == PropertyAttributes::Generic && that->m_template->m_fallbackPropertySetter) {
- Handle<Value> result = that->m_template->m_fallbackPropertyQuery(String::New(name), that->fallbackAccessorInfo());
- if (!result.IsEmpty())
- return propertyAttributesToFlags(result);
- }
-
- return flags;
- }
-
- static PropertyAttributes queryIndexed(const QV4::Managed *m, uint index)
- {
- const V4V8Object *that = static_cast<const V4V8Object*>(m);
- if (that->m_template->m_indexedPropertyQuery) {
- Handle<Value> result = that->m_template->m_indexedPropertyQuery(index, that->indexedAccessorInfo());
- if (!result.IsEmpty())
- return propertyAttributesToFlags(result);
- }
-
- return BaseClass::queryIndexed(m, index);
- }
-
- static bool deleteProperty(QV4::Managed *m, ExecutionContext *ctx, QV4::String *name)
- {
- V4V8Object *that = static_cast<V4V8Object*>(m);
- if (that->m_template->m_namedPropertyDeleter) {
- Handle<Value> result = that->m_template->m_namedPropertyDeleter(String::New(name), that->namedAccessorInfo());
- if (!result.IsEmpty())
- return result->BooleanValue();
- }
-
- bool result = BaseClass::deleteProperty(m, ctx, name);
-
- if (that->m_template->m_fallbackPropertyDeleter) {
- Handle<Value> interceptResult = that->m_template->m_fallbackPropertyDeleter(String::New(name), that->fallbackAccessorInfo());
- if (!interceptResult.IsEmpty())
- result = interceptResult->BooleanValue();
- }
-
- return result;
- }
-
- static bool deleteIndexedProperty(QV4::Managed *m, ExecutionContext *ctx, uint index)
- {
- V4V8Object *that = static_cast<V4V8Object*>(m);
- if (that->m_template->m_indexedPropertyDeleter) {
- Handle<Value> result = that->m_template->m_indexedPropertyDeleter(index, that->indexedAccessorInfo());
- if (!result.IsEmpty())
- return result->BooleanValue();
- }
- return BaseClass::deleteIndexedProperty(m, ctx, index);
- }
-};
-
-template<>
-DEFINE_MANAGED_VTABLE(V4V8Object<QV4::Object>);
-template<>
-DEFINE_MANAGED_VTABLE(V4V8Object<QV4::FunctionObject>);
-template<>
-DEFINE_MANAGED_VTABLE(V4V8Object<QV4::FunctionPrototype>);
-
-struct V4V8Function : public V4V8Object<QV4::FunctionObject>
-{
- V4V8Function(QV4::ExecutionEngine *engine, FunctionTemplate *functionTemplate)
- : V4V8Object<QV4::FunctionObject>(engine, 0)
- {
- vtbl = &static_vtbl;
- m_functionTemplate = functionTemplate;
- initProperties(m_functionTemplate.data());
- }
-
-protected:
- static const ManagedVTable static_vtbl;
-
- static QV4::Value call(QV4::Managed *m, ExecutionContext *context, const QV4::Value &thisObject, QV4::Value *args, int argc)
- {
- V4V8Function *that = static_cast<V4V8Function*>(m);
- Arguments arguments(args, argc, thisObject, false, that->m_functionTemplate->m_data.value());
- QV4::Value result = QV4::Value::undefinedValue();
- if (that->m_functionTemplate->m_callback)
- result = that->m_functionTemplate->m_callback(arguments);
- else if (that->m_functionTemplate->m_newCallback) {
- QV4::SimpleCallContext ctx;
- ctx.initSimpleCallContext(context->engine);
- ctx.strictMode = true;
- ctx.thisObject = thisObject;
- ctx.arguments = args;
- ctx.argumentCount = argc;
- context->engine->pushContext(&ctx);
- try {
- result = that->m_functionTemplate->m_newCallback(&ctx);
- } catch (QV4::Exception &ex) {
- ex.partiallyUnwindContext(context);
- throw;
- }
- context->engine->popContext();
- }
- return result;
- }
-
- static QV4::Value construct(QV4::Managed *m, ExecutionContext *context, QV4::Value *args, int argc)
- {
- V4V8Function *that = static_cast<V4V8Function*>(m);
-
- QV4::Object *obj = that->m_functionTemplate->InstanceTemplate()->NewInstance()->v4Value().asObject();
- QV4::Value proto = that->Managed::get(context, context->engine->id_prototype);
- if (proto.isObject())
- obj->prototype = proto.objectValue();
-
- Arguments arguments(args, argc, QV4::Value::fromObject(obj), true, that->m_functionTemplate->m_data.value());
-
- QV4::Value result = QV4::Value::undefinedValue();
- if (that->m_functionTemplate->m_callback)
- result = that->m_functionTemplate->m_callback(arguments);
- else if (that->m_functionTemplate->m_newCallback) {
- QV4::SimpleCallContext ctx;
- ctx.initSimpleCallContext(context->engine);
- ctx.strictMode = true;
- ctx.arguments = args;
- ctx.argumentCount = argc;
- context->engine->pushContext(&ctx);
- try {
- result = that->m_functionTemplate->m_newCallback(&ctx);
- } catch (QV4::Exception &ex) {
- ex.partiallyUnwindContext(context);
- throw;
- }
- context->engine->popContext();
- }
- if (result.isObject())
- return result;
- return QV4::Value::fromObject(obj);
-
- }
-
- QExplicitlySharedDataPointer<FunctionTemplate> m_functionTemplate;
-};
-
-DEFINE_MANAGED_VTABLE(V4V8Function);
-
-FunctionTemplate::FunctionTemplate(InvocationCallback callback, Handle<Value> data)
- : m_callback(callback)
- , m_newCallback(0)
-{
- m_instanceTemplate = Handle<ObjectTemplate>();
- m_prototypeTemplate = Handle<ObjectTemplate>();
- m_data = data->v4Value();
-}
-
-FunctionTemplate::FunctionTemplate(NewInvocationCallback callback, Handle<Value> data)
- : m_callback(0)
- , m_newCallback(callback)
-{
- m_instanceTemplate = Handle<ObjectTemplate>();
- m_prototypeTemplate = Handle<ObjectTemplate>();
- m_data = data->v4Value();
-}
-
-Handle<FunctionTemplate> FunctionTemplate::New(InvocationCallback callback, Handle<Value> data)
-{
- FunctionTemplate *ft = new FunctionTemplate(callback, data);
- return Handle<FunctionTemplate>(ft);
-}
-
-Handle<FunctionTemplate> FunctionTemplate::New(NewInvocationCallback callback, Handle<Value> data)
-{
- FunctionTemplate *ft = new FunctionTemplate(callback, data);
- return Handle<FunctionTemplate>(ft);
-}
-
-Handle<Function> FunctionTemplate::GetFunction()
-{
- QV4::ExecutionEngine *engine = currentEngine();
- QV4::Object *o = new (engine->memoryManager) V4V8Function(engine, this);
- QV4::Object *proto = new (engine->memoryManager) V4V8Object<QV4::FunctionPrototype>(engine, m_prototypeTemplate.get());
- o->put(engine->current, engine->id_prototype, QV4::Value::fromObject(proto));
- return QV4::Value::fromObject(o);
-}
-
-Handle<ObjectTemplate> FunctionTemplate::InstanceTemplate()
-{
- if (m_instanceTemplate.IsEmpty())
- m_instanceTemplate = ObjectTemplate::New();
- return m_instanceTemplate;
-}
-
-Handle<ObjectTemplate> FunctionTemplate::PrototypeTemplate()
-{
- if (m_prototypeTemplate.IsEmpty())
- m_prototypeTemplate = ObjectTemplate::New();
- return m_prototypeTemplate;
-}
-
-
-Handle<ObjectTemplate> ObjectTemplate::New()
-{
- ObjectTemplate *ot = new ObjectTemplate;
- return Handle<ObjectTemplate>(ot);
-}
-
-Handle<Object> ObjectTemplate::NewInstance()
-{
- QV4::ExecutionEngine *engine = currentEngine();
- QV4::Object *o = new (engine->memoryManager) V4V8Object<QV4::Object>(engine, this);
- o->prototype = engine->objectPrototype;
-
- return QV4::Value::fromObject(o);
-}
-
-void ObjectTemplate::SetAccessor(Handle<String> name, AccessorGetter getter, AccessorSetter setter, Handle<Value> data, AccessControl settings, PropertyAttribute attribute)
-{
- QV4::ExecutionEngine *engine = currentEngine();
-
- Accessor a;
- if (getter) {
- QV4::FunctionObject *wrappedGetter = new (engine->memoryManager) V8AccessorGetter(engine->rootContext, name, getter, data);
- a.getter = QV4::Value::fromObject(wrappedGetter);
- }
- if (setter) {
- QV4::FunctionObject *wrappedSetter = new (engine->memoryManager) V8AccessorSetter(engine->rootContext, name, setter, data);
- a.setter = QV4::Value::fromObject(wrappedSetter);
- }
- a.attribute = attribute;
- a.name = name->v4Value();
- m_accessors << a;
-}
-
-void ObjectTemplate::SetNamedPropertyHandler(NamedPropertyGetter getter, NamedPropertySetter setter, NamedPropertyQuery query, NamedPropertyDeleter deleter, NamedPropertyEnumerator enumerator, Handle<Value> data)
-{
- m_namedPropertyGetter = getter;
- m_namedPropertySetter = setter;
- m_namedPropertyQuery = query;
- m_namedPropertyDeleter = deleter;
- m_namedPropertyEnumerator = enumerator;
- m_namedPropertyData = data->v4Value();
-}
-
-void ObjectTemplate::SetFallbackPropertyHandler(NamedPropertyGetter getter, NamedPropertySetter setter, NamedPropertyQuery query, NamedPropertyDeleter deleter, NamedPropertyEnumerator enumerator, Handle<Value> data)
-{
- m_fallbackPropertyGetter = getter;
- m_fallbackPropertySetter = setter;
- m_fallbackPropertyQuery = query;
- m_fallbackPropertyDeleter = deleter;
- m_fallbackPropertyEnumerator = enumerator;
- assert(!enumerator);
- m_fallbackPropertyData = data->v4Value();
-}
-
-void ObjectTemplate::SetIndexedPropertyHandler(IndexedPropertyGetter getter, IndexedPropertySetter setter, IndexedPropertyQuery query, IndexedPropertyDeleter deleter, IndexedPropertyEnumerator enumerator, Handle<Value> data)
-{
- m_indexedPropertyGetter = getter;
- m_indexedPropertySetter = setter;
- m_indexedPropertyQuery = query;
- m_indexedPropertyDeleter = deleter;
- m_indexedPropertyEnumerator = enumerator;
- m_indexedPropertyData = data->v4Value();
-}
-
-int ObjectTemplate::InternalFieldCount()
-{
- Q_UNIMPLEMENTED();
- Q_UNREACHABLE();
-}
-
-void ObjectTemplate::SetInternalFieldCount(int value)
-{
- Q_UNIMPLEMENTED();
-}
-
-bool ObjectTemplate::HasExternalResource()
-{
- // we always reserve the space for the external resource
- return true;
-}
-
-void ObjectTemplate::SetHasExternalResource(bool value)
-{
- // no need for this, we always reserve the space for the external resource
- Q_UNUSED(value);
-}
-
-ObjectTemplate::ObjectTemplate()
-{
- m_namedPropertyGetter = 0;
- m_namedPropertySetter = 0;
- m_namedPropertyQuery = 0;
- m_namedPropertyDeleter = 0;
- m_namedPropertyEnumerator = 0;
-
- m_fallbackPropertyGetter = 0;
- m_fallbackPropertySetter = 0;
- m_fallbackPropertyQuery = 0;
- m_fallbackPropertyDeleter = 0;
- m_fallbackPropertyEnumerator = 0;
-
- m_indexedPropertyGetter = 0;
- m_indexedPropertySetter = 0;
- m_indexedPropertyQuery = 0;
- m_indexedPropertyDeleter = 0;
- m_indexedPropertyEnumerator = 0;
-}
-
-Handle<Value> ThrowException(Handle<Value> exception)
-{
- __qmljs_throw(currentEngine()->current, exception->v4Value());
- return Handle<Value>();
-}
-
-
-Handle<Value> Exception::ReferenceError(Handle<String> message)
-{
- Q_UNUSED(message);
- QV4::Object *o = currentEngine()->newReferenceErrorObject(message->ToString()->asQString());
- return QV4::Value::fromObject(o);
-}
-
-Handle<Value> Exception::SyntaxError(Handle<String> message)
-{
- Q_UNUSED(message);
- QV4::Object *o = currentEngine()->newSyntaxErrorObject(currentEngine()->current, 0);
- return QV4::Value::fromObject(o);
-}
-
-Handle<Value> Exception::TypeError(Handle<String> message)
-{
- Q_UNUSED(message);
- QV4::Object *o = currentEngine()->newTypeErrorObject(message->ToString()->asQString());
- return QV4::Value::fromObject(o);
-}
-
-Handle<Value> Exception::Error(Handle<String> message)
-{
- Q_UNUSED(message);
- QV4::Object *o = currentEngine()->newErrorObject(QV4::Value::fromString(currentEngine()->current, message->ToString()->asQString()));
- return QV4::Value::fromObject(o);
-}
-
-
-static QThreadStorage<Isolate*> currentIsolate;
-
-Isolate::Isolate()
-{
-}
-
-Isolate::~Isolate()
-{
-}
-
-ExecutionEngine *Isolate::GetEngine()
-{
- return Isolate::GetCurrent()->m_engines.top();
-}
-
-void Isolate::SetEngine(ExecutionEngine *e)
-{
- Isolate *i = GetCurrent();
- if (e)
- i->m_engines.push(e);
- else
- i->m_engines.pop();
-}
-
-Isolate *Isolate::GetCurrent()
-{
- if (!currentIsolate.hasLocalData()) {
- Isolate *i = new Isolate;
- currentIsolate.setLocalData(i);
- }
- return currentIsolate.localData();
-}
-
-
-Handle<Value> Context::GetCallingScriptData()
-{
- Q_UNIMPLEMENTED();
- Q_UNREACHABLE();
-}
-
-}
+++ /dev/null
-/****************************************************************************
-**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the V4VM 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 Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-/** \mainpage V8 API Reference Guide
- *
- * V8 is Google's open source JavaScript engine.
- *
- * This set of documents provides reference material generated from the
- * V8 header file, include/v8.h.
- *
- * For other documentation see http://code.google.com/apis/v8/
- */
-
-#ifndef V8_H_
-#define V8_H_
-
-#include "qv4global_p.h"
-#include "qv4string_p.h"
-#include "qv4value_p.h"
-#include <QStack>
-#include <QSharedData>
-
-namespace QV4 {
-struct Value;
-struct String;
-struct ExecutionEngine;
-struct Object;
-class MemoryManager;
-struct SimpleCallContext;
-}
-
-
-#include <stdint.h>
-
-#define V8EXPORT Q_QML_EXPORT
-
-/**
- * The v8 JavaScript engine.
- */
-namespace v8 {
-
-class Context;
-class String;
-class StringObject;
-class Value;
-class Utils;
-class NumberObject;
-class Object;
-class Array;
-class External;
-class Function;
-class Date;
-class ImplementationUtilities;
-class Signature;
-class AccessorSignature;
-template <class T> struct Handle;
-class FunctionTemplate;
-class ObjectTemplate;
-class AccessorInfo;
-class Isolate;
-class TryCatch;
-
-V8EXPORT void *gcProtect(void *handle);
-V8EXPORT void gcProtect(void *memoryManager, void *handle);
-V8EXPORT void gcUnprotect(void *memoryManager, void *handle);
-
-// --- Weak Handles ---
-
-/**
- * A weak reference callback function.
- *
- * This callback should either explicitly invoke Dispose on |object| if
- * V8 wrapper is not needed anymore, or 'revive' it by invocation of MakeWeak.
- *
- * \param object the weak global object to be reclaimed by the garbage collector
- * \param parameter the value passed in when making the weak global object
- */
-//typedef void (*WeakReferenceCallback)(Persistent<Value> object,
-// void* parameter);
-
-
-// --- Handles ---
-
-#define TYPE_CHECK(T, S) \
- while (false) { \
- *(static_cast<T* volatile*>(0)) = static_cast<S*>(0); \
- }
-
-Q_QML_EXPORT quint64 qv8_get_value(const QV4::Value &v);
-
-/**
- * An object reference managed by the v8 garbage collector.
- *
- * All objects returned from v8 have to be tracked by the garbage
- * collector so that it knows that the objects are still alive. Also,
- * because the garbage collector may move objects, it is unsafe to
- * point directly to an object. Instead, all objects are stored in
- * handles which are known by the garbage collector and updated
- * whenever an object moves. Handles should always be passed by value
- * (except in cases like out-parameters) and they should never be
- * allocated on the heap.
- *
- * There are two types of handles: local and persistent handles.
- * Local handles are light-weight and transient and typically used in
- * local operations. They are managed by HandleScopes. Persistent
- * handles can be used when storing objects across several independent
- * operations and have to be explicitly deallocated when they're no
- * longer used.
- *
- * It is safe to extract the object stored in the handle by
- * dereferencing the handle (for instance, to extract the Object* from
- * a Handle<Object>); the value will still be governed by a handle
- * behind the scenes and the same rules apply to these values as to
- * their handles.
- */
-
-template <typename T>
-struct Handle;
-
-template <typename T>
-struct HandleOperations
-{
- static void init(Handle<T> *handle)
- {
-#if QT_POINTER_SIZE == 8
- handle->val = quint64(Handle<T>::_Deleted_Type) << Handle<T>::Tag_Shift;
-#else
- handle->tag = Handle<T>::_Deleted_Type;
- handle->int_32 = 0;
-#endif
- }
- static void init(Handle<T> *handle, T *other)
- {
- handle->val = *reinterpret_cast<quint64 *>(other);
- }
-
- static void init(Handle<T> *handle, const QV4::Value &v)
- {
- handle->val = qv8_get_value(v);
- }
-
- static void ref(Handle<T> *)
- {
- }
-
- static void deref(Handle<T> *)
- {
- }
-
- static void *protect(Handle<T> *handle)
- {
- return gcProtect(handle);
- }
-
- static void protect(void *memoryManager, Handle<T> *handle)
- {
- gcProtect(memoryManager, handle);
- }
-
- static void unProtect(void *memoryManager, Handle<T> *handle)
- {
- gcUnprotect(memoryManager, handle);
- }
-
- static bool isEmpty(const Handle<T> *handle)
- {
- return handle->tag == Handle<T>::_Deleted_Type;
- }
-
- static T *get(const Handle<T> *handle)
- {
- return const_cast<T*>(reinterpret_cast<const T*>(handle));
- }
-};
-
-#define DEFINE_REFCOUNTED_HANDLE_OPERATIONS(Type) \
- template <> \
- struct HandleOperations<Type> \
- { \
- static void init(Handle<Type> *handle) \
- { \
- handle->object = 0; \
- } \
- static void init(Handle<Type> *handle, Type *obj) \
- { \
- handle->object = obj; \
- } \
- \
- static void ref(Handle<Type> *handle) \
- { \
- if (handle->object) \
- handle->object->ref.ref(); \
- } \
- \
- static void deref(Handle<Type> *handle) \
- { \
- if (handle->object && !handle->object->ref.deref()) { \
- delete handle->object; \
- handle->object = 0; \
- } \
- } \
- static void *protect(Handle<Type> *) { return 0; } \
- static void protect(void *, Handle<Type> *) {} \
- static void unProtect(void *, Handle<Type> *) {} \
- static bool isEmpty(const Handle<Type> *handle) \
- { \
- return handle->object == 0; \
- } \
- static Type *get(const Handle<Type> *handle) \
- { \
- return handle->object; \
- } \
- \
- };
-
-template <typename T>
-struct Handle {
- Handle()
- {
- HandleOperations<T>::init(this);
- }
- template <typename Other>
- Handle(const Handle<Other> &that)
- : val(that.val)
- {
- HandleOperations<T>::ref(this);
- }
-
- explicit Handle(T *obj)
- {
- HandleOperations<T>::init(this, obj);
- HandleOperations<T>::ref(this);
- }
-
- Handle(const QV4::Value &v) {
- HandleOperations<T>::init(this, v);
- }
-
- Handle(const Handle<T> &other)
- : val(other.val)
- {
- HandleOperations<T>::ref(this);
- }
- Handle<T> &operator=(const Handle<T> &other)
- {
- if (this == &other)
- return *this;
- HandleOperations<T>::deref(this);
- this->val = other.val;
- HandleOperations<T>::ref(this);
- return *this;
- }
- ~Handle()
- {
- HandleOperations<T>::deref(this);
- }
-
- bool IsEmpty() const { return HandleOperations<T>::isEmpty(this); }
-
- T *operator->() const { return HandleOperations<T>::get(this); }
-
- T *get() const { return HandleOperations<T>::get(this); }
-
- template <typename Source>
- static Handle<T> Cast(Handle<Source> that)
- {
- return that.template As<T>();
- }
-
- template <typename Target>
- Handle<Target> As()
- {
- return Handle<Target>(*this);
- }
-
- void Clear()
- {
- val = 0;
- }
-
- template <class S> inline bool operator==(Handle<S> that) const {
- return val == that.val;
- }
- template <class S> inline bool operator!=(Handle<S> that) const {
- return val != that.val;
- }
-
- enum Masks {
- NotDouble_Mask = 0xfffc0000,
- Type_Mask = 0xffff8000,
- Immediate_Mask = NotDouble_Mask | 0x00008000,
- Tag_Shift = 32
- };
-
- enum ValueType {
- Undefined_Type = Immediate_Mask | 0x00000,
- Null_Type = Immediate_Mask | 0x10000,
- Boolean_Type = Immediate_Mask | 0x20000,
- Integer_Type = Immediate_Mask | 0x30000,
- Object_Type = NotDouble_Mask | 0x00000,
- String_Type = NotDouble_Mask | 0x10000,
- Deleted_Type = NotDouble_Mask | 0x30000
- };
-
- enum ImmediateFlags {
- ConvertibleToInt = Immediate_Mask | 0x1
- };
-
- enum ValueTypeInternal {
- _Undefined_Type = Undefined_Type,
- _Deleted_Type = Deleted_Type,
- _Null_Type = Null_Type | ConvertibleToInt,
- _Boolean_Type = Boolean_Type | ConvertibleToInt,
- _Integer_Type = Integer_Type | ConvertibleToInt,
- _Object_Type = Object_Type,
- _String_Type = String_Type
- };
-
- union {
- T *object;
- quint64 val;
- double dbl;
- struct {
-#if Q_BYTE_ORDER != Q_LITTLE_ENDIAN
- uint tag;
-#endif
- union {
- uint uint_32;
- int int_32;
-#if QT_POINTER_SIZE == 4
- T *o;
-#endif
- };
-#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
- uint tag;
-#endif
- };
- };
-};
-
-// --- Special objects ---
-
-
-
-// --- Value ---
-
-
-/**
- * The superclass of all JavaScript values and objects.
- */
-class V8EXPORT Value {
- public:
- /**
- * Returns true if this value is the undefined value. See ECMA-262
- * 4.3.10.
- */
- bool IsUndefined() const;
-
- /**
- * Returns true if this value is the null value. See ECMA-262
- * 4.3.11.
- */
- bool IsNull() const;
-
- /**
- * Returns true if this value is true.
- */
- bool IsTrue() const;
-
- /**
- * Returns true if this value is false.
- */
- bool IsFalse() const;
-
- /**
- * Returns true if this value is an instance of the String type.
- * See ECMA-262 8.4.
- */
- bool IsString() const;
-
- /**
- * Returns true if this value is a function.
- */
- bool IsFunction() const;
-
- /**
- * Returns true if this value is an array.
- */
- bool IsArray() const;
-
- /**
- * Returns true if this value is an object.
- */
- bool IsObject() const;
-
- /**
- * Returns true if this value is boolean.
- */
- bool IsBoolean() const;
-
- /**
- * Returns true if this value is a number.
- */
- bool IsNumber() const;
-
- /**
- * Returns true if this value is external.
- */
- bool IsExternal() const;
-
- /**
- * Returns true if this value is a 32-bit signed integer.
- */
- bool IsInt32() const;
-
- /**
- * Returns true if this value is a 32-bit unsigned integer.
- */
- bool IsUint32() const;
-
- /**
- * Returns true if this value is a Date.
- */
- bool IsDate() const;
-
- /**
- * Returns true if this value is a Boolean object.
- */
- bool IsBooleanObject() const;
-
- /**
- * Returns true if this value is a Number object.
- */
- bool IsNumberObject() const;
-
- /**
- * Returns true if this value is a String object.
- */
- bool IsStringObject() const;
-
- /**
- * Returns true if this value is a RegExp.
- */
- bool IsRegExp() const;
-
- /**
- * Returns true if this value is an Error.
- */
- bool IsError() const;
-
- Handle<String> ToString() const;
- Handle<Object> ToObject() const;
-
- bool BooleanValue() const;
- double NumberValue() const;
- int64_t IntegerValue() const;
- uint32_t Uint32Value() const;
- int32_t Int32Value() const;
-
- /** JS == */
- bool Equals(Handle<Value> that) const;
- bool StrictEquals(Handle<Value> that) const;
-
- static Handle<Value> NewFromInternalValue(quint64 val)
- {
- Handle<Value> res;
- res.val = val;
- return res;
- }
-
- QV4::Value v4Value() const;
- static Handle<Value> fromV4Value(const QV4::Value &v4Value);
-
-};
-
-
-/**
- * A JavaScript string value (ECMA-262, 4.3.17).
- */
-class V8EXPORT String : public Value {
- public:
-
- /**
- * An ExternalStringResource is a wrapper around a two-byte string
- * buffer that resides outside V8's heap. Implement an
- * ExternalStringResource to manage the life cycle of the underlying
- * buffer. Note that the string data must be immutable.
- */
- class V8EXPORT ExternalStringResource {
- public:
- /**
- * Override the destructor to manage the life cycle of the underlying
- * buffer.
- */
- virtual ~ExternalStringResource() {}
-
- /**
- * The string data from the underlying buffer.
- */
- virtual const uint16_t* data() const = 0;
-
- /**
- * The length of the string. That is, the number of two-byte characters.
- */
- virtual size_t length() const = 0;
-
- virtual void Dispose() { delete this; }
-
- protected:
- ExternalStringResource() {}
- };
-
- /**
- * Get the ExternalStringResource for an external string. Returns
- * NULL if IsExternal() doesn't return true.
- */
- ExternalStringResource* GetExternalStringResource() const;
-
- static String* Cast(v8::Value* obj);
-
- /**
- * Allocates a new string from either UTF-8 encoded or ASCII data.
- * The second parameter 'length' gives the buffer length.
- * If the data is UTF-8 encoded, the caller must
- * be careful to supply the length parameter.
- * If it is not given, the function calls
- * 'strlen' to determine the buffer length, it might be
- * wrong if 'data' contains a null character.
- */
- static Handle<String> New(const char* data, int length = -1);
-
- /** Allocates a new string from 16-bit character codes.*/
- static Handle<String> New(const uint16_t* data, int length = -1);
-
- static Handle<String> New(QV4::String *s);
-
- /**
- * Creates a new external string using the data defined in the given
- * resource. When the external string is no longer live on V8's heap the
- * resource will be disposed by calling its Dispose method. The caller of
- * this function should not otherwise delete or modify the resource. Neither
- * should the underlying buffer be deallocated or modified except through the
- * destructor of the external string resource.
- */
- static Handle<String> NewExternal(ExternalStringResource* resource);
-
-
- QString asQString() const;
- QV4::String *asV4String() const;
-};
-
-
-enum PropertyAttribute {
- None = 0,
- ReadOnly = 1 << 0,
- DontEnum = 1 << 1,
- DontDelete = 1 << 2
-};
-
-/**
- * Accessor[Getter|Setter] are used as callback functions when
- * setting|getting a particular property. See Object and ObjectTemplate's
- * method SetAccessor.
- */
-typedef Handle<Value> (*AccessorGetter)(Handle<String> property,
- const AccessorInfo& info);
-
-
-typedef void (*AccessorSetter)(Handle<String> property,
- Handle<Value> value,
- const AccessorInfo& info);
-
-
-/**
- * Access control specifications.
- *
- * Some accessors should be accessible across contexts. These
- * accessors have an explicit access control parameter which specifies
- * the kind of cross-context access that should be allowed.
- *
- * Additionally, for security, accessors can prohibit overwriting by
- * accessors defined in JavaScript. For objects that have such
- * accessors either locally or in their prototype chain it is not
- * possible to overwrite the accessor by using __defineGetter__ or
- * __defineSetter__ from JavaScript code.
- */
-enum AccessControl {
- DEFAULT = 0,
- ALL_CAN_READ = 1,
- ALL_CAN_WRITE = 1 << 1,
- PROHIBITS_OVERWRITING = 1 << 2
-};
-
-
-/**
- * A JavaScript object (ECMA-262, 4.3.3)
- */
-class V8EXPORT Object : public Value {
- public:
- bool Set(Handle<Value> key,
- Handle<Value> value,
- PropertyAttribute attribs = None);
-
- bool Set(uint32_t index,
- Handle<Value> value);
-
- Handle<Value> Get(Handle<Value> key);
-
- Handle<Value> Get(uint32_t index);
-
- // TODO(1245389): Replace the type-specific versions of these
- // functions with generic ones that accept a Handle<Value> key.
- bool Has(Handle<String> key);
-
- bool Delete(Handle<String> key);
-
- bool Has(uint32_t index);
-
- bool Delete(uint32_t index);
-
- bool SetAccessor(Handle<String> name,
- AccessorGetter getter,
- AccessorSetter setter = 0,
- Handle<Value> data = Handle<Value>(),
- AccessControl settings = DEFAULT,
- PropertyAttribute attribute = None);
-
- /**
- * Returns an array containing the names of the enumerable properties
- * of this object, including properties from prototype objects. The
- * array returned by this method contains the same values as would
- * be enumerated by a for-in statement over this object.
- */
- Handle<Array> GetPropertyNames();
-
- /**
- * This function has the same functionality as GetPropertyNames but
- * the returned array doesn't contain the names of properties from
- * prototype objects.
- */
- Handle<Array> GetOwnPropertyNames();
-
- /**
- * Get the prototype object. This does not skip objects marked to
- * be skipped by __proto__ and it does not consult the security
- * handler.
- */
- Handle<Value> GetPrototype();
-
- /**
- * Set the prototype object. This does not skip objects marked to
- * be skipped by __proto__ and it does not consult the security
- * handler.
- */
- bool SetPrototype(Handle<Value> prototype);
-
- /** Gets the value in an internal field. */
- Handle<Value> GetInternalField(int index);
- /** Sets the value in an internal field. */
- void SetInternalField(int index, Handle<Value> value);
-
- class V8EXPORT ExternalResource { // NOLINT
- public:
- ExternalResource() {}
- virtual ~ExternalResource() {}
-
- virtual void Dispose() { delete this; }
-
- private:
- // Disallow copying and assigning.
- ExternalResource(const ExternalResource&);
- void operator=(const ExternalResource&);
- };
-
- void SetExternalResource(ExternalResource *);
- ExternalResource *GetExternalResource();
-
- // Testers for local properties.
- bool HasOwnProperty(Handle<String> key);
-
- /**
- * Returns the identity hash for this object. The current implementation
- * uses a hidden property on the object to store the identity hash.
- *
- * The return value will never be 0. Also, it is not guaranteed to be
- * unique.
- */
- int GetIdentityHash();
-
- /**
- * Clone this object with a fast but shallow copy. Values will point
- * to the same values as the original object.
- */
- Handle<Object> Clone();
-
-
- /**
- * Checks whether a callback is set by the
- * ObjectTemplate::SetCallAsFunctionHandler method.
- * When an Object is callable this method returns true.
- */
- bool IsCallable();
-
- /**
- * Call an Object as a function if a callback is set by the
- * ObjectTemplate::SetCallAsFunctionHandler method.
- */
- Handle<Value> CallAsFunction(Handle<Object> recv,
- int argc,
- Handle<Value> argv[]);
-
- /**
- * Call an Object as a constructor if a callback is set by the
- * ObjectTemplate::SetCallAsFunctionHandler method.
- * Note: This method behaves like the Function::NewInstance method.
- */
- Handle<Value> CallAsConstructor(int argc,
- Handle<Value> argv[]);
-
- static Handle<Object> New();
- static Object* Cast(Value* obj);
-};
-
-
-/**
- * An instance of the built-in array constructor (ECMA-262, 15.4.2).
- */
-class V8EXPORT Array : public Object {
- public:
- uint32_t Length() const;
-
- /**
- * Creates a JavaScript array with the given length. If the length
- * is negative the returned array will have length 0.
- */
- static Handle<Array> New(int length = 0);
-
- static Array* Cast(Value* obj);
-};
-
-
-/**
- * A JavaScript function object (ECMA-262, 15.3).
- */
-class V8EXPORT Function : public Object {
- public:
- Handle<Object> NewInstance() const;
- Handle<Object> NewInstance(int argc, Handle<Value> argv[]) const;
- Handle<Value> Call(Handle<Object> recv,
- int argc,
- Handle<Value> argv[]);
- Handle<Value> GetName() const;
-
- static Function* Cast(Value* obj);
-};
-
-
-
-/**
- * A JavaScript value that wraps a C++ void*. This type of value is
- * mainly used to associate C++ data structures with JavaScript
- * objects.
- *
- * The Wrap function V8 will return the most optimal Value object wrapping the
- * C++ void*. The type of the value is not guaranteed to be an External object
- * and no assumptions about its type should be made. To access the wrapped
- * value Unwrap should be used, all other operations on that object will lead
- * to unpredictable results.
- */
-class V8EXPORT External : public Value {
- public:
- static Handle<Value> Wrap(void* data);
- static void* Unwrap(Handle<Value> obj);
-
- static Handle<External> New(void* value);
- static External* Cast(Value* obj);
- void* Value() const;
-};
-
-
-// --- Templates ---
-
-
-/**
- * The superclass of object and function templates.
- */
-class V8EXPORT Template : public QSharedData {
- public:
- /** Adds a property to each instance created by this template.*/
- void Set(Handle<String> name, Handle<Value> value,
- PropertyAttribute attributes = None);
- void Set(const char* name, Handle<Value> value);
-
- struct Property {
- QV4::PersistentValue name;
- QV4::PersistentValue value;
- PropertyAttribute attributes;
- };
- QVector<Property> m_properties;
- };
-
-DEFINE_REFCOUNTED_HANDLE_OPERATIONS(Template)
-
-/**
- * The argument information given to function call callbacks. This
- * class provides access to information about the context of the call,
- * including the receiver, the number and values of arguments, and
- * the holder of the function.
- */
-class V8EXPORT Arguments {
- public:
- Arguments(const QV4::Value *args, int argc, const QV4::Value &thisObject, bool isConstructor,
- const Handle<Value> &data);
- int Length() const;
- Handle<Value> operator[](int i) const;
- Handle<Object> This() const;
- QV4::Value ThisV4() const;
- Handle<Object> Holder() const;
- bool IsConstructCall() const;
- Handle<Value> Data() const;
- Isolate* GetIsolate() const;
-
-private:
- QVector<QV4::PersistentValue> m_args;
- QV4::PersistentValue m_thisObject;
- bool m_isConstructor;
- QV4::PersistentValue m_data;
-};
-
-
-/**
- * The information passed to an accessor callback about the context
- * of the property access.
- */
-class V8EXPORT AccessorInfo {
- public:
- AccessorInfo(const QV4::Value &thisObject, const Handle<Value> &data);
- Isolate* GetIsolate() const;
- Handle<Value> Data() const;
- Handle<Object> This() const;
- Handle<Object> Holder() const;
-private:
- QV4::PersistentValue m_this;
- QV4::PersistentValue m_data;
-};
-
-
-typedef QV4::Value (*InvocationCallback)(const Arguments& args);
-typedef QV4::Value (*NewInvocationCallback)(QV4::SimpleCallContext *);
-
-/**
- * NamedProperty[Getter|Setter] are used as interceptors on object.
- * See ObjectTemplate::SetNamedPropertyHandler.
- */
-typedef Handle<Value> (*NamedPropertyGetter)(Handle<String> property,
- const AccessorInfo& info);
-
-
-/**
- * Returns the value if the setter intercepts the request.
- * Otherwise, returns an empty handle.
- */
-typedef Handle<Value> (*NamedPropertySetter)(Handle<String> property,
- Handle<Value> value,
- const AccessorInfo& info);
-
-/**
- * Returns a non-empty handle if the interceptor intercepts the request.
- * The result is an integer encoding property attributes (like v8::None,
- * v8::DontEnum, etc.)
- */
-typedef Handle<Value> (*NamedPropertyQuery)(Handle<String> property,
- const AccessorInfo& info);
-
-
-/**
- * Returns a non-empty handle if the deleter intercepts the request.
- * The return value is true if the property could be deleted and false
- * otherwise.
- */
-typedef Handle<Value> (*NamedPropertyDeleter)(Handle<String> property,
- const AccessorInfo& info);
-
-/**
- * Returns an array containing the names of the properties the named
- * property getter intercepts.
- */
-typedef Handle<Array> (*NamedPropertyEnumerator)(const AccessorInfo& info);
-
-
-/**
- * Returns the value of the property if the getter intercepts the
- * request. Otherwise, returns an empty handle.
- */
-typedef Handle<Value> (*IndexedPropertyGetter)(uint32_t index,
- const AccessorInfo& info);
-
-
-/**
- * Returns the value if the setter intercepts the request.
- * Otherwise, returns an empty handle.
- */
-typedef Handle<Value> (*IndexedPropertySetter)(uint32_t index,
- Handle<Value> value,
- const AccessorInfo& info);
-
-
-/**
- * Returns a non-empty handle if the interceptor intercepts the request.
- * The result is an integer encoding property attributes.
- */
-typedef Handle<Value> (*IndexedPropertyQuery)(uint32_t index,
- const AccessorInfo& info);
-
-/**
- * Returns a non-empty handle if the deleter intercepts the request.
- * The return value is true if the property could be deleted and false
- * otherwise.
- */
-typedef Handle<Value> (*IndexedPropertyDeleter)(uint32_t index,
- const AccessorInfo& info);
-
-/**
- * Returns an array containing the indices of the properties the
- * indexed property getter intercepts.
- */
-typedef Handle<Array> (*IndexedPropertyEnumerator)(const AccessorInfo& info);
-
-
-/**
- * A FunctionTemplate is used to create functions at runtime. There
- * can only be one function created from a FunctionTemplate in a
- * context. The lifetime of the created function is equal to the
- * lifetime of the context. So in case the embedder needs to create
- * temporary functions that can be collected using Scripts is
- * preferred.
- *
- * A FunctionTemplate can have properties, these properties are added to the
- * function object when it is created.
- *
- * A FunctionTemplate has a corresponding instance template which is
- * used to create object instances when the function is used as a
- * constructor. Properties added to the instance template are added to
- * each object instance.
- *
- * A FunctionTemplate can have a prototype template. The prototype template
- * is used to create the prototype object of the function.
- *
- * The following example shows how to use a FunctionTemplate:
- *
- * \code
- * v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New();
- * t->Set("func_property", QV4::Value::fromDouble(1));
- *
- * v8::Local<v8::Template> proto_t = t->PrototypeTemplate();
- * proto_t->Set("proto_method", v8::FunctionTemplate::New(InvokeCallback));
- * proto_t->Set("proto_const", QV4::Value::fromDouble(2));
- *
- * v8::Local<v8::ObjectTemplate> instance_t = t->InstanceTemplate();
- * instance_t->SetAccessor("instance_accessor", InstanceAccessorCallback);
- * instance_t->SetNamedPropertyHandler(PropertyHandlerCallback, ...);
- * instance_t->Set("instance_property", Number::New(3));
- *
- * v8::Local<v8::Function> function = t->GetFunction();
- * v8::Local<v8::Object> instance = function->NewInstance();
- * \endcode
- *
- * Let's use "function" as the JS variable name of the function object
- * and "instance" for the instance object created above. The function
- * and the instance will have the following properties:
- *
- * \code
- * func_property in function == true;
- * function.func_property == 1;
- *
- * function.prototype.proto_method() invokes 'InvokeCallback'
- * function.prototype.proto_const == 2;
- *
- * instance instanceof function == true;
- * instance.instance_accessor calls 'InstanceAccessorCallback'
- * instance.instance_property == 3;
- * \endcode
- *
- * A FunctionTemplate can inherit from another one by calling the
- * FunctionTemplate::Inherit method. The following graph illustrates
- * the semantics of inheritance:
- *
- * \code
- * FunctionTemplate Parent -> Parent() . prototype -> { }
- * ^ ^
- * | Inherit(Parent) | .__proto__
- * | |
- * FunctionTemplate Child -> Child() . prototype -> { }
- * \endcode
- *
- * A FunctionTemplate 'Child' inherits from 'Parent', the prototype
- * object of the Child() function has __proto__ pointing to the
- * Parent() function's prototype object. An instance of the Child
- * function has all properties on Parent's instance templates.
- *
- * Let Parent be the FunctionTemplate initialized in the previous
- * section and create a Child FunctionTemplate by:
- *
- * \code
- * Local<FunctionTemplate> parent = t;
- * Local<FunctionTemplate> child = FunctionTemplate::New();
- * child->Inherit(parent);
- *
- * Local<Function> child_function = child->GetFunction();
- * Local<Object> child_instance = child_function->NewInstance();
- * \endcode
- *
- * The Child function and Child instance will have the following
- * properties:
- *
- * \code
- * child_func.prototype.__proto__ == function.prototype;
- * child_instance.instance_accessor calls 'InstanceAccessorCallback'
- * child_instance.instance_property == 3;
- * \endcode
- */
-class V8EXPORT FunctionTemplate : public Template {
- public:
- /** Creates a function template.*/
- static Handle<FunctionTemplate> New(
- InvocationCallback callback = 0,
- Handle<Value> data = Handle<Value>());
- static Handle<FunctionTemplate> New(
- NewInvocationCallback callback,
- Handle<Value> data = Handle<Value>());
- /** Returns the unique function instance in the current execution context.*/
- Handle<Function> GetFunction();
-
- /** Get the InstanceTemplate. */
- Handle<ObjectTemplate> InstanceTemplate();
-
- /**
- * A PrototypeTemplate is the template used to create the prototype object
- * of the function created by this template.
- */
- Handle<ObjectTemplate> PrototypeTemplate();
-
-private:
- FunctionTemplate(InvocationCallback callback, Handle<Value> data);
- FunctionTemplate(NewInvocationCallback callback, Handle<Value> data);
- friend class V4V8Function;
- InvocationCallback m_callback;
- NewInvocationCallback m_newCallback;
- QV4::PersistentValue m_data;
- Handle<ObjectTemplate> m_instanceTemplate;
- Handle<ObjectTemplate> m_prototypeTemplate;
-};
-
-DEFINE_REFCOUNTED_HANDLE_OPERATIONS(FunctionTemplate)
-
-
-/**
- * An ObjectTemplate is used to create objects at runtime.
- *
- * Properties added to an ObjectTemplate are added to each object
- * created from the ObjectTemplate.
- */
-class V8EXPORT ObjectTemplate : public Template {
- public:
- /** Creates an ObjectTemplate. */
- static Handle<ObjectTemplate> New();
-
- /** Creates a new instance of this template.*/
- Handle<Object> NewInstance();
-
- /**
- * Sets an accessor on the object template.
- *
- * Whenever the property with the given name is accessed on objects
- * created from this ObjectTemplate the getter and setter callbacks
- * are called instead of getting and setting the property directly
- * on the JavaScript object.
- *
- * \param name The name of the property for which an accessor is added.
- * \param getter The callback to invoke when getting the property.
- * \param setter The callback to invoke when setting the property.
- * \param data A piece of data that will be passed to the getter and setter
- * callbacks whenever they are invoked.
- * \param settings Access control settings for the accessor. This is a bit
- * field consisting of one of more of
- * DEFAULT = 0, ALL_CAN_READ = 1, or ALL_CAN_WRITE = 2.
- * The default is to not allow cross-context access.
- * ALL_CAN_READ means that all cross-context reads are allowed.
- * ALL_CAN_WRITE means that all cross-context writes are allowed.
- * The combination ALL_CAN_READ | ALL_CAN_WRITE can be used to allow all
- * cross-context access.
- * \param attribute The attributes of the property for which an accessor
- * is added.
- * \param signature The signature describes valid receivers for the accessor
- * and is used to perform implicit instance checks against them. If the
- * receiver is incompatible (i.e. is not an instance of the constructor as
- * defined by FunctionTemplate::HasInstance()), an implicit TypeError is
- * thrown and no callback is invoked.
- */
- void SetAccessor(Handle<String> name,
- AccessorGetter getter,
- AccessorSetter setter = 0,
- Handle<Value> data = Handle<Value>(),
- AccessControl settings = DEFAULT,
- PropertyAttribute attribute = None);
-
- /**
- * Sets a named property handler on the object template.
- *
- * Whenever a named property is accessed on objects created from
- * this object template, the provided callback is invoked instead of
- * accessing the property directly on the JavaScript object.
- *
- * \param getter The callback to invoke when getting a property.
- * \param setter The callback to invoke when setting a property.
- * \param query The callback to invoke to check if a property is present,
- * and if present, get its attributes.
- * \param deleter The callback to invoke when deleting a property.
- * \param enumerator The callback to invoke to enumerate all the named
- * properties of an object.
- * \param data A piece of data that will be passed to the callbacks
- * whenever they are invoked.
- */
- void SetNamedPropertyHandler(NamedPropertyGetter getter,
- NamedPropertySetter setter = 0,
- NamedPropertyQuery query = 0,
- NamedPropertyDeleter deleter = 0,
- NamedPropertyEnumerator enumerator = 0,
- Handle<Value> data = Handle<Value>());
- void SetFallbackPropertyHandler(NamedPropertyGetter getter,
- NamedPropertySetter setter = 0,
- NamedPropertyQuery query = 0,
- NamedPropertyDeleter deleter = 0,
- NamedPropertyEnumerator enumerator = 0,
- Handle<Value> data = Handle<Value>());
-
- /**
- * Sets an indexed property handler on the object template.
- *
- * Whenever an indexed property is accessed on objects created from
- * this object template, the provided callback is invoked instead of
- * accessing the property directly on the JavaScript object.
- *
- * \param getter The callback to invoke when getting a property.
- * \param setter The callback to invoke when setting a property.
- * \param query The callback to invoke to check if an object has a property.
- * \param deleter The callback to invoke when deleting a property.
- * \param enumerator The callback to invoke to enumerate all the indexed
- * properties of an object.
- * \param data A piece of data that will be passed to the callbacks
- * whenever they are invoked.
- */
- void SetIndexedPropertyHandler(IndexedPropertyGetter getter,
- IndexedPropertySetter setter = 0,
- IndexedPropertyQuery query = 0,
- IndexedPropertyDeleter deleter = 0,
- IndexedPropertyEnumerator enumerator = 0,
- Handle<Value> data = Handle<Value>());
-
- /**
- * Gets the number of internal fields for objects generated from
- * this template.
- */
- int InternalFieldCount();
-
- /**
- * Sets the number of internal fields for objects generated from
- * this template.
- */
- void SetInternalFieldCount(int value);
-
- /**
- * Sets whether the object can store an "external resource" object.
- */
- bool HasExternalResource();
- void SetHasExternalResource(bool value);
-
- struct Accessor {
- QV4::PersistentValue getter;
- QV4::PersistentValue setter;
- QV4::PersistentValue name;
- PropertyAttribute attribute;
- };
-
- QVector<Accessor> m_accessors;
-
- NamedPropertyGetter m_namedPropertyGetter;
- NamedPropertySetter m_namedPropertySetter;
- NamedPropertyQuery m_namedPropertyQuery;
- NamedPropertyDeleter m_namedPropertyDeleter;
- NamedPropertyEnumerator m_namedPropertyEnumerator;
- QV4::PersistentValue m_namedPropertyData;
-
- NamedPropertyGetter m_fallbackPropertyGetter;
- NamedPropertySetter m_fallbackPropertySetter;
- NamedPropertyQuery m_fallbackPropertyQuery;
- NamedPropertyDeleter m_fallbackPropertyDeleter;
- NamedPropertyEnumerator m_fallbackPropertyEnumerator;
- QV4::PersistentValue m_fallbackPropertyData;
-
- IndexedPropertyGetter m_indexedPropertyGetter;
- IndexedPropertySetter m_indexedPropertySetter;
- IndexedPropertyQuery m_indexedPropertyQuery;
- IndexedPropertyDeleter m_indexedPropertyDeleter;
- IndexedPropertyEnumerator m_indexedPropertyEnumerator;
- QV4::PersistentValue m_indexedPropertyData;
-
- private:
- ObjectTemplate();
- };
-
-DEFINE_REFCOUNTED_HANDLE_OPERATIONS(ObjectTemplate)
-
-// --- Exceptions ---
-
-
-/**
- * Schedules an exception to be thrown when returning to JavaScript. When an
- * exception has been scheduled it is illegal to invoke any JavaScript
- * operation; the caller must return immediately and only after the exception
- * has been handled does it become legal to invoke JavaScript operations.
- */
-Handle<Value> V8EXPORT ThrowException(Handle<Value> exception);
-
-/**
- * Create new error objects by calling the corresponding error object
- * constructor with the message.
- */
-class V8EXPORT Exception {
- public:
- static Handle<Value> ReferenceError(Handle<String> message);
- static Handle<Value> SyntaxError(Handle<String> message);
- static Handle<Value> TypeError(Handle<String> message);
- static Handle<Value> Error(Handle<String> message);
-};
-
-
-// --- User Object Comparison Callback ---
-typedef bool (*UserObjectComparisonCallback)(Handle<Object> lhs,
- Handle<Object> rhs);
-
-// --- Garbage Collection Callbacks ---
-
-/**
- * Applications can register callback functions which will be called
- * before and after a garbage collection. Allocations are not
- * allowed in the callback functions, you therefore cannot manipulate
- * objects (set or delete properties for example) since it is possible
- * such operations will result in the allocation of objects.
- */
-enum GCType {
- kGCTypeScavenge = 1 << 0,
- kGCTypeMarkSweepCompact = 1 << 1,
- kGCTypeAll = kGCTypeScavenge | kGCTypeMarkSweepCompact
-};
-
-enum GCCallbackFlags {
- kNoGCCallbackFlags = 0,
- kGCCallbackFlagCompacted = 1 << 0
-};
-
-typedef void (*GCPrologueCallback)(GCType type, GCCallbackFlags flags);
-typedef void (*GCCallback)();
-
-
-
-/**
- * Isolate represents an isolated instance of the V8 engine. V8
- * isolates have completely separate states. Objects from one isolate
- * must not be used in other isolates. When V8 is initialized a
- * default isolate is implicitly created and entered. The embedder
- * can create additional isolates and use them in parallel in multiple
- * threads. An isolate can be entered by at most one thread at any
- * given time. The Locker/Unlocker API must be used to synchronize.
- */
-class V8EXPORT Isolate {
- public:
- Isolate();
- ~Isolate();
-
- /**
- * Returns the entered isolate for the current thread or NULL in
- * case there is no current isolate.
- */
- static Isolate* GetCurrent();
-
- static QV4::ExecutionEngine *GetEngine();
- static void SetEngine(QV4::ExecutionEngine *e);
-
- private:
- friend class Context;
- QStack<QV4::ExecutionEngine*> m_engines;
-};
-
-
-
-/**
- * A sandboxed execution context with its own set of built-in objects
- * and functions.
- */
-class V8EXPORT Context {
-public:
- /**
- * Returns the context of the calling JavaScript code. That is the
- * context of the top-most JavaScript frame. If there are no
- * JavaScript frames an empty handle is returned.
- */
- static Handle<Value> GetCallingScriptData();
-
-private:
- Context() {}
- ~Context() {}
-};
-
-
-} // namespace v8
-
-
-#undef V8EXPORT
-#undef TYPE_CHECK
-
-
-#endif // V8_H_
$$PWD/qv4unwindhelper.cpp \
$$PWD/qv4serialize.cpp \
$$PWD/qv4script.cpp \
- $$PWD/qv4v8.cpp \
$$PWD/qv4executableallocator.cpp \
$$PWD/qv4sequenceobject.cpp \
$$PWD/qv4include.cpp \
$$PWD/qv4unwindhelper_p-arm.h \
$$PWD/qv4serialize_p.h \
$$PWD/qv4script_p.h \
- $$PWD/qv4v8_p.h \
$$PWD/qv4util_p.h \
$$PWD/qv4executableallocator_p.h \
$$PWD/qv4sequenceobject_p.h \
#include "qv4functionobject_p.h"
#include "qv4dateobject_p.h"
#include "qv4runtime_p.h"
-#include "qv4v8_p.h"
#include "qv4variantobject_p.h"
#include "qv4regexpobject_p.h"
#include "qv8engine_p.h"
#include <QtCore/qglobal.h>
#include <private/qv4object_p.h>
-#include <qv4v8_p.h>
class QQmlEngine;
class QV8Engine;
+++ /dev/null
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtQml module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE: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 Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <private/qv4v8_p.h>
qMetaTypeId<QList<int> >();
m_v4Engine = new QV4::ExecutionEngine;
- v8::Isolate::SetEngine(m_v4Engine);
m_v4Engine->v8Engine = this;
QV4::QObjectWrapper::initializeBindings(m_v4Engine);
delete m_listModelData;
m_listModelData = 0;
- v8::Isolate::SetEngine(0);
delete m_v4Engine;
}
include(script.pri)
HEADERS += \
- $$PWD/qv8_p.h \
$$PWD/qv8debug_p.h \
$$PWD/qv8profiler_p.h \
$$PWD/qv8engine_p.h \
#include <private/qqmlcomponent_p.h>
-#include <private/qv8_p.h>
-
QT_BEGIN_NAMESPACE
static const QQuickItemPrivate::ChangeTypes watchedChanges
#include "qquickitemchangelistener_p.h"
#include <qqmlincubator.h>
-#include <private/qv8_p.h>
-
#include <private/qv4value_p.h>
QT_BEGIN_NAMESPACE
#include <private/qquickvaluetypes_p.h>
#include <private/qquickapplication_p.h>
#include <private/qqmlglobal_p.h>
-#include <private/qv8_p.h>
#include <private/qv8engine_p.h>
#include <QtGui/QGuiApplication>
#include <QtCore/qnumeric.h>
#include <stdlib.h>
-#include <private/qv4v8_p.h>
-
Q_DECLARE_METATYPE(QList<int>)
Q_DECLARE_METATYPE(QObjectList)
void setWidth(int) { }
};
-void MyQmlObject::v8function(QQmlV4Function *)
+void MyQmlObject::v8function(QQmlV4Function *function)
{
- const char *error = "Exception thrown from within QObject slot";
- v8::ThrowException(v8::Exception::Error(v8::String::New(error)));
+ QV8Engine::getV4(function->engine())->current->throwError(QStringLiteral("Exception thrown from within QObject slot"));
}
static QJSValue script_api(QQmlEngine *engine, QJSEngine *scriptEngine)
}
}
-static inline bool evaluate_error(QV8Engine *engine, v8::Handle<v8::Object> o, const char *source)
+static inline bool evaluate_error(QV8Engine *engine, const QV4::Value &o, const char *source)
{
QString functionSource = QLatin1String("(function(object) { return ") +
QLatin1String(source) + QLatin1String(" })");
QV4::FunctionObject *function = program.run().asFunctionObject();
if (!function)
return false;
- QV4::Value args[] = { o->v4Value() };
+ QV4::Value args[] = { o };
function->call(engine->global(), args, 1);
} catch (QV4::Exception &e) {
e.accept(ctx);
return false;
}
-static inline bool evaluate_value(QV8Engine *engine, v8::Handle<v8::Object> o,
- const char *source, v8::Handle<v8::Value> result)
+static inline bool evaluate_value(QV8Engine *engine, const QV4::Value &o,
+ const char *source, const QV4::Value &result)
{
QString functionSource = QLatin1String("(function(object) { return ") +
QLatin1String(source) + QLatin1String(" })");
QV4::FunctionObject *function = program.run().asFunctionObject();
if (!function)
return false;
- QV4::Value args[] = { o->v4Value() };
+ QV4::Value args[] = { o };
QV4::Value value = function->call(engine->global(), args, 1);
- return __qmljs_strict_equal(value, result->v4Value());
+ return __qmljs_strict_equal(value, result);
} catch (QV4::Exception &e) {
e.accept(ctx);
}
return false;
}
-static inline v8::Handle<v8::Value> evaluate(QV8Engine *engine, v8::Handle<v8::Object> o,
+static inline QV4::Value evaluate(QV8Engine *engine, const QV4::Value & o,
const char *source)
{
QString functionSource = QLatin1String("(function(object) { return ") +
try {
QV4::FunctionObject *function = program.run().asFunctionObject();
if (!function)
- return v8::Handle<v8::Value>();
- QV4::Value args[] = { o->v4Value() };
+ return QV4::Value::emptyValue();
+ QV4::Value args[] = { o };
QV4::Value value = function->call(engine->global(), args, 1);
return value;
} catch (QV4::Exception &e) {
e.accept(ctx);
}
- return v8::Handle<v8::Value>();
+ return QV4::Value::emptyValue();
}
#define EVALUATE_ERROR(source) evaluate_error(engine, object, source)
QV8Engine *engine = ep->v8engine();
- v8::Handle<v8::Object> object = QV4::QObjectWrapper::wrap(QV8Engine::getV4(engine), o);
+ QV4::Value object = QV4::QObjectWrapper::wrap(QV8Engine::getV4(engine), o);
// Non-existent methods
o->reset();
o->reset();
{
- v8::Handle<v8::Value> ret = EVALUATE("object.method_NoArgs_QPointF()");
- QVERIFY(!ret.IsEmpty());
- QCOMPARE(engine->toVariant(ret->v4Value(), -1), QVariant(QPointF(123, 4.5)));
+ QV4::Value ret = EVALUATE("object.method_NoArgs_QPointF()");
+ QVERIFY(!ret.isEmpty());
+ QCOMPARE(engine->toVariant(ret, -1), QVariant(QPointF(123, 4.5)));
QCOMPARE(o->error(), false);
QCOMPARE(o->invoked(), 3);
QCOMPARE(o->actuals().count(), 0);
o->reset();
{
- v8::Handle<v8::Value> ret = EVALUATE("object.method_NoArgs_QObject()");
- QV4::QObjectWrapper *qobjectWrapper = ret->v4Value().as<QV4::QObjectWrapper>();
+ QV4::Value ret = EVALUATE("object.method_NoArgs_QObject()");
+ QV4::QObjectWrapper *qobjectWrapper = ret.as<QV4::QObjectWrapper>();
QVERIFY(qobjectWrapper);
QCOMPARE(qobjectWrapper->object(), (QObject *)o);
QCOMPARE(o->error(), false);
o->reset();
{
- v8::Handle<v8::Value> ret = EVALUATE("object.method_NoArgs_QScriptValue()");
- QVERIFY(ret->IsString());
- QCOMPARE(ret->v4Value().toQString(), QString("Hello world"));
+ QV4::Value ret = EVALUATE("object.method_NoArgs_QScriptValue()");
+ QVERIFY(ret.isString());
+ QCOMPARE(ret.toQString(), QString("Hello world"));
QCOMPARE(o->error(), false);
QCOMPARE(o->invoked(), 6);
QCOMPARE(o->actuals().count(), 0);