diff options
46 files changed, 457 insertions, 2151 deletions
diff --git a/src/qml/debugger/qv8debugservice.cpp b/src/qml/debugger/qv8debugservice.cpp index 19008d9ede..d9d4323d00 100644 --- a/src/qml/debugger/qv8debugservice.cpp +++ b/src/qml/debugger/qv8debugservice.cpp @@ -41,7 +41,7 @@ #include "qv8debugservice_p.h" #include "qqmldebugservice_p_p.h" -#include <private/qjsconverter_impl_p.h> +#include <private/qjsconverter_p.h> #include <private/qv4compiler_p.h> #include <private/qv8engine_p.h> diff --git a/src/qml/debugger/qv8profilerservice.cpp b/src/qml/debugger/qv8profilerservice.cpp index 5d8873bada..4e24a73f6a 100644 --- a/src/qml/debugger/qv8profilerservice.cpp +++ b/src/qml/debugger/qv8profilerservice.cpp @@ -41,7 +41,7 @@ #include "qv8profilerservice_p.h" #include "qqmldebugservice_p_p.h" -#include "private/qjsconverter_impl_p.h" +#include "private/qjsconverter_p.h" #include <private/qv8profiler_p.h> #include <QtCore/QHash> diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp index c9ce4773c3..99e82bb30e 100644 --- a/src/qml/qml/qqmllocale.cpp +++ b/src/qml/qml/qqmllocale.cpp @@ -42,7 +42,7 @@ #include "qqmllocale_p.h" #include "qqmlengine_p.h" #include <private/qqmlcontext_p.h> -#include <private/qjsconverter_impl_p.h> +#include <private/qjsconverter_p.h> #include <QtCore/qnumeric.h> #include <QtCore/qdatetime.h> diff --git a/src/qml/qml/v4/qv4bindings.cpp b/src/qml/qml/v4/qv4bindings.cpp index b680bf798b..ac5bd17288 100644 --- a/src/qml/qml/v4/qv4bindings.cpp +++ b/src/qml/qml/v4/qv4bindings.cpp @@ -50,10 +50,7 @@ #include <private/qv8_p.h> #include <private/qjsconverter_p.h> -#include <private/qjsconverter_impl_p.h> -#include <private/qjsvalue_impl_p.h> -#include <private/qjsvalueiterator_impl_p.h> -#include <private/qv8engine_impl_p.h> +#include <private/qv8engine_p.h> #include <private/qqmlaccessors_p.h> #include <private/qqmlprofilerservice_p.h> @@ -1286,7 +1283,7 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks, } else { QV8Engine *v8engine = QQmlEnginePrivate::get(context->engine)->v8engine(); new (output.gethandleptr()) v8::Handle<v8::Value>( - QJSValuePrivate::get(tmp)->asV8Value(v8engine)); + v8::Value::fromVmValue(QJSValuePrivate::get(tmp)->value)); V8HANDLE_REGISTER(instr->unaryop.output); } } diff --git a/src/qml/qml/v4vm/qv4dateobject.cpp b/src/qml/qml/v4vm/qv4dateobject.cpp index ec0293971f..f1504b3bb8 100644 --- a/src/qml/qml/v4vm/qv4dateobject.cpp +++ b/src/qml/qml/v4vm/qv4dateobject.cpp @@ -768,6 +768,16 @@ void DatePrototype::init(ExecutionContext *ctx, const Value &ctor) defineDefaultProperty(ctx, QStringLiteral("toJSON"), method_toJSON, 1); } +double DatePrototype::toJSDate(const QDateTime &dateTime) +{ + return FromDateTime(dateTime); +} + +QDateTime DatePrototype::toQDateTime(double d) +{ + return ToDateTime(d, Qt::LocalTime); +} + double DatePrototype::getThisDate(ExecutionContext *ctx) { if (DateObject *thisObject = ctx->thisObject.asDateObject()) diff --git a/src/qml/qml/v4vm/qv4dateobject_p.h b/src/qml/qml/v4vm/qv4dateobject_p.h index 4445b66502..2e5366edd7 100644 --- a/src/qml/qml/v4vm/qv4dateobject_p.h +++ b/src/qml/qml/v4vm/qv4dateobject_p.h @@ -47,6 +47,8 @@ QT_BEGIN_NAMESPACE +class QDateTime; + namespace QQmlJS { namespace VM { @@ -71,6 +73,9 @@ struct DatePrototype: DateObject DatePrototype(ExecutionEngine *engine): DateObject(engine, Value::fromDouble(qSNaN())) {} void init(ExecutionContext *ctx, const Value &ctor); + static double toJSDate(const QDateTime &dateTime); + static QDateTime toQDateTime(double d); + static double getThisDate(ExecutionContext *ctx); static Value method_parse(SimpleCallContext *ctx); diff --git a/src/qml/qml/v4vm/qv4engine_p.h b/src/qml/qml/v4vm/qv4engine_p.h index d7bb3aadd9..7777ca59eb 100644 --- a/src/qml/qml/v4vm/qv4engine_p.h +++ b/src/qml/qml/v4vm/qv4engine_p.h @@ -53,6 +53,8 @@ QT_BEGIN_NAMESPACE +class QJSEngine; + namespace QQmlJS { namespace Debugging { @@ -123,6 +125,8 @@ struct Q_QML_EXPORT ExecutionEngine VM::Function *globalCode; + QJSEngine *publicEngine; + Value objectCtor; Value stringCtor; Value numberCtor; diff --git a/src/qml/qml/v4vm/qv4jsir_p.h b/src/qml/qml/v4vm/qv4jsir_p.h index 6fa43275f5..64a467c732 100644 --- a/src/qml/qml/v4vm/qv4jsir_p.h +++ b/src/qml/qml/v4vm/qv4jsir_p.h @@ -38,8 +38,8 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#ifndef QV4IR_P_H -#define QV4IR_P_H +#ifndef QV4JSIR_P_H +#define QV4JSIR_P_H // // W A R N I N G diff --git a/src/qml/qml/v4vm/qv4math_p.h b/src/qml/qml/v4vm/qv4math_p.h index 0699c0c971..1cbb2ab490 100644 --- a/src/qml/qml/v4vm/qv4math_p.h +++ b/src/qml/qml/v4vm/qv4math_p.h @@ -46,7 +46,7 @@ #endif // QMLJS_LLVM_RUNTIME #include <cmath> -#if !defined(QMLJS_LLVM_RUNTIME) && COMPILER(GCC) && (CPU(X86_64) || CPU(X86)) +#if !defined(QMLJS_LLVM_RUNTIME) && defined(Q_CC_GCC) && defined(Q_PROCESSOR_X86) #define QMLJS_INLINE_MATH #define QMLJS_READONLY __attribute((const)) #endif diff --git a/src/qml/qml/v4vm/qv4runtime.cpp b/src/qml/qml/v4vm/qv4runtime.cpp index 6f1df366d8..fd22db4d7c 100644 --- a/src/qml/qml/v4vm/qv4runtime.cpp +++ b/src/qml/qml/v4vm/qv4runtime.cpp @@ -434,10 +434,9 @@ void __qmljs_inplace_ushr_member(ExecutionContext *ctx, const Value &base, Strin o->inplaceBinOp(ctx, __qmljs_ushr, name, rhs); } -double __qmljs_string_to_number(const String *string) +double __qmljs_string_to_number(const QString &string) { - QString s = string->toQString(); - s = s.trimmed(); + QString s = string.trimmed(); if (s.startsWith(QLatin1String("0x")) || s.startsWith(QLatin1String("0X"))) return s.toLong(0, 16); bool ok; diff --git a/src/qml/qml/v4vm/qv4runtime_p.h b/src/qml/qml/v4vm/qv4runtime_p.h index d7934ac4fd..1672573f85 100644 --- a/src/qml/qml/v4vm/qv4runtime_p.h +++ b/src/qml/qml/v4vm/qv4runtime_p.h @@ -153,7 +153,7 @@ VM::Function *__qmljs_register_function(ExecutionContext *ctx, String *name, // strings -double __qmljs_string_to_number(const String *string); +double __qmljs_string_to_number(const QString &s); Value __qmljs_string_from_number(ExecutionContext *ctx, double number); String *__qmljs_string_concat(ExecutionContext *ctx, String *first, String *second); @@ -305,7 +305,7 @@ inline double __qmljs_to_number(const Value &value) case Value::Integer_Type: return value.int_32; case Value::String_Type: - return __qmljs_string_to_number(value.stringValue()); + return __qmljs_string_to_number(value.stringValue()->toQString()); case Value::Object_Type: { Value prim = __qmljs_to_primitive(value, NUMBER_HINT); return __qmljs_to_number(prim); diff --git a/src/qml/qml/v4vm/qv4string.cpp b/src/qml/qml/v4vm/qv4string.cpp index 24d75e561a..919f0c299f 100644 --- a/src/qml/qml/v4vm/qv4string.cpp +++ b/src/qml/qml/v4vm/qv4string.cpp @@ -183,7 +183,7 @@ uint String::toUInt(bool *ok) const return stringHash; // ### this conversion shouldn't be required - double d = __qmljs_string_to_number(this); + double d = __qmljs_string_to_number(toQString()); uint l = (uint)d; if (d == l) return l; diff --git a/src/qml/qml/v4vm/qv4v8.cpp b/src/qml/qml/v4vm/qv4v8.cpp index 50db008e96..b1a680ec96 100644 --- a/src/qml/qml/v4vm/qv4v8.cpp +++ b/src/qml/qml/v4vm/qv4v8.cpp @@ -1963,6 +1963,11 @@ void Isolate::setException(const VM::Value &ex) } } +ExecutionEngine *Isolate::GetEngine() +{ + return Isolate::GetCurrent()->GetCurrentContext()->GetEngine(); +} + Isolate *Isolate::GetCurrent() { if (!currentIsolate.hasLocalData()) diff --git a/src/qml/qml/v4vm/qv4v8_p.h b/src/qml/qml/v4vm/qv4v8_p.h index f7957cd68f..c351833ca2 100644 --- a/src/qml/qml/v4vm/qv4v8_p.h +++ b/src/qml/qml/v4vm/qv4v8_p.h @@ -2289,6 +2289,8 @@ class V8EXPORT Isolate { Context *GetCurrentContext() { return m_contextStack.top(); } void setException(const QQmlJS::VM::Value &ex); + static QQmlJS::VM::ExecutionEngine *GetEngine(); + private: friend class Context; friend class TryCatch; diff --git a/src/qml/qml/v4vm/qv4value.cpp b/src/qml/qml/v4vm/qv4value.cpp index 6112c3716b..38da68b2d2 100644 --- a/src/qml/qml/v4vm/qv4value.cpp +++ b/src/qml/qml/v4vm/qv4value.cpp @@ -169,7 +169,7 @@ Value Value::property(ExecutionContext *ctx, String *name) const PersistentValue::PersistentValue(ExecutionEngine *e, const Value &val) - : d(PersistentValuePrivate::create(e, val)) + : d(new PersistentValuePrivate(e, val)) { } @@ -195,14 +195,23 @@ PersistentValue::~PersistentValue() d->deref(); } -PersistentValuePrivate *PersistentValuePrivate::create(ExecutionEngine *e, const Value &v) +PersistentValuePrivate::PersistentValuePrivate(const Value &v) + : value(v) + , refcount(1) + , engine(0) + , next(0) { - PersistentValuePrivate *d = new PersistentValuePrivate; - d->engine = e; - d->next = e->memoryManager->m_persistentValues; - e->memoryManager->m_persistentValues = d; - d->value = v; - d->refcount = 1; + assert(!v.asManaged()); +} + + +PersistentValuePrivate::PersistentValuePrivate(ExecutionEngine *e, const Value &v) + : value(v) + , refcount(1) + , engine(e) + , next(engine->memoryManager->m_persistentValues) +{ + engine->memoryManager->m_persistentValues = this; } void PersistentValuePrivate::deref() diff --git a/src/qml/qml/v4vm/qv4value_p.h b/src/qml/qml/v4vm/qv4value_p.h index 281e6a7853..d707844e11 100644 --- a/src/qml/qml/v4vm/qv4value_p.h +++ b/src/qml/qml/v4vm/qv4value_p.h @@ -48,7 +48,7 @@ #include <QtCore/QDebug> #include "qv4managed_p.h" -#include <wtf/MathExtras.h> +//#include <wtf/MathExtras.h> QT_BEGIN_NAMESPACE @@ -546,12 +546,19 @@ inline Value Managed::call(ExecutionContext *context, const Value &thisObject, V struct PersistentValuePrivate { + PersistentValuePrivate() + : value(Value::undefinedValue()) + , refcount(1) + , engine(0) + , next(0) + {} + PersistentValuePrivate(ExecutionEngine *e, const Value &v); + PersistentValuePrivate(const Value &v); Value value; int refcount; ExecutionEngine *engine; PersistentValuePrivate *next; - static PersistentValuePrivate *create(ExecutionEngine *e, const Value &v); void ref() { ++refcount; } void deref(); }; diff --git a/src/qml/qml/v8/qjsconverter_impl_p.h b/src/qml/qml/v8/qjsconverter_impl_p.h index 4b17d5ed31..165373c421 100644 --- a/src/qml/qml/v8/qjsconverter_impl_p.h +++ b/src/qml/qml/v8/qjsconverter_impl_p.h @@ -147,23 +147,6 @@ QString QJSConverter::toString(double value) return QString::fromLatin1(buf.constData()); } -// return a mask of v8::PropertyAttribute that may also contains QScriptValue::PropertyGetter or QScriptValue::PropertySetter -uint QJSConverter::toPropertyAttributes(const QFlags<QJSValuePrivate::PropertyFlag>& flags) -{ - uint attr = 0; - if (flags.testFlag(QJSValuePrivate::ReadOnly)) - attr |= v8::ReadOnly; - if (flags.testFlag(QJSValuePrivate::Undeletable)) - attr |= v8::DontDelete; - if (flags.testFlag(QJSValuePrivate::SkipInEnumeration)) - attr |= v8::DontEnum; - // if (flags.testFlag(QScriptValue::PropertyGetter)) - // attr |= QScriptValue::PropertyGetter; - // if (flags.testFlag(QScriptValue::PropertySetter)) - // attr |= QScriptValue::PropertySetter; - return attr; -} - // Converts a JS RegExp to a QRegExp. // The conversion is not 100% exact since ECMA regexp and QRegExp // have different semantics/flags, but we try to do our best. diff --git a/src/qml/qml/v8/qjsconverter_p.h b/src/qml/qml/v8/qjsconverter_p.h index 5f6633f580..3522b3885a 100644 --- a/src/qml/qml/v8/qjsconverter_p.h +++ b/src/qml/qml/v8/qjsconverter_p.h @@ -65,45 +65,43 @@ QT_BEGIN_NAMESPACE */ class QJSConverter { public: - static inline quint32 toArrayIndex(const QString& string); + static quint32 toArrayIndex(const QString& string); - static inline QString toString(v8::Handle<v8::String> jsString); - static inline v8::Local<v8::String> toString(const QString& string); - static inline QString toString(double value); + static QString toString(v8::Handle<v8::String> jsString); + static v8::Local<v8::String> toString(const QString& string); + static QString toString(double value); enum { PropertyAttributeMask = v8::ReadOnly | v8::DontDelete | v8::DontEnum, }; - // return a mask of v8::PropertyAttribute that may also contains QScriptValue::PropertyGetter or QScriptValue::PropertySetter - static inline uint toPropertyAttributes(const QFlags<QJSValuePrivate::PropertyFlag>& flags); // Converts a JS RegExp to a QRegExp. // The conversion is not 100% exact since ECMA regexp and QRegExp // have different semantics/flags, but we try to do our best. - static inline QRegExp toRegExp(v8::Handle<v8::RegExp> jsRegExp); + static QRegExp toRegExp(v8::Handle<v8::RegExp> jsRegExp); // Converts a QRegExp to a JS RegExp. // The conversion is not 100% exact since ECMA regexp and QRegExp // have different semantics/flags, but we try to do our best. - static inline v8::Local<v8::RegExp> toRegExp(const QRegExp &re); + static v8::Local<v8::RegExp> toRegExp(const QRegExp &re); // Converts a QStringList to JS. // The result is a new Array object with length equal to the length // of the QStringList, and the elements being the QStringList's // elements converted to JS Strings. - static inline v8::Local<v8::Array> toStringList(const QStringList &lst); + static v8::Local<v8::Array> toStringList(const QStringList &lst); // Converts a JS Array object to a QStringList. // The result is a QStringList with length equal to the length // of the JS Array, and elements being the JS Array's elements // converted to QStrings. - static inline QStringList toStringList(v8::Handle<v8::Array> jsArray); + static QStringList toStringList(v8::Handle<v8::Array> jsArray); // Converts a JS Date to a QDateTime. - static inline QDateTime toDateTime(v8::Handle<v8::Date> jsDate); + static QDateTime toDateTime(v8::Handle<v8::Date> jsDate); // Converts a QDateTime to a JS Date. - static inline v8::Local<v8::Value> toDateTime(const QDateTime &dt); + static v8::Local<v8::Value> toDateTime(const QDateTime &dt); }; QT_END_NAMESPACE diff --git a/src/qml/qml/v8/qjsengine.cpp b/src/qml/qml/v8/qjsengine.cpp index 5b1464afe6..76bb6e8bf8 100644 --- a/src/qml/qml/v8/qjsengine.cpp +++ b/src/qml/qml/v8/qjsengine.cpp @@ -44,7 +44,6 @@ #include "qjsvalue.h" #include "qjsvalue_p.h" #include "qscriptisolate_p.h" -#include "qscript_impl_p.h" #include "qv8engine_p.h" #include <QtCore/qdatetime.h> @@ -63,6 +62,8 @@ #include <qwaitcondition.h> #include <private/qqmlglobal_p.h> +#include <private/qjsconverter_impl_p.h> + #undef Q_D #undef Q_Q #define Q_D(blah) @@ -257,7 +258,7 @@ QJSValue QJSEngine::evaluate(const QString& program, const QString& fileName, in Q_D(QJSEngine); QScriptIsolate api(d, QScriptIsolate::NotNullEngine); v8::HandleScope handleScope; - return QJSValuePrivate::get(d->evaluate(program, fileName, qmlSourceCoordinate(lineNumber))); + return d->evaluate(program, fileName, qmlSourceCoordinate(lineNumber)); } /*! @@ -273,7 +274,8 @@ QJSValue QJSEngine::newObject() Q_D(QJSEngine); QScriptIsolate api(d, QScriptIsolate::NotNullEngine); v8::HandleScope handleScope; - return QJSValuePrivate::get(new QJSValuePrivate(d, v8::Object::New())); + QQmlJS::VM::ExecutionEngine *engine = d->m_v4Engine; + return new QJSValuePrivate(engine, QQmlJS::VM::Value::fromObject(engine->newObject())); } /*! @@ -354,51 +356,52 @@ QJSValue QJSEngine::create(int type, const void *ptr) bool QJSEngine::convertV2(const QJSValue &value, int type, void *ptr) { QJSValuePrivate *vp = QJSValuePrivate::get(value); - QV8Engine *engine = vp->engine(); + QQmlJS::VM::ExecutionEngine *e = vp->engine; + QV8Engine *engine = e ? QV8Engine::get(e->publicEngine) : 0; if (engine) { QScriptIsolate api(engine, QScriptIsolate::NotNullEngine); v8::HandleScope handleScope; - return engine->metaTypeFromJS(*vp, type, ptr); + return engine->metaTypeFromJS(v8::Value::fromVmValue(vp->getValue(engine->m_v4Engine)), type, ptr); } else { switch (type) { case QMetaType::Bool: - *reinterpret_cast<bool*>(ptr) = vp->toBool(); + *reinterpret_cast<bool*>(ptr) = vp->value.toBoolean(); return true; case QMetaType::Int: - *reinterpret_cast<int*>(ptr) = vp->toInt32(); + *reinterpret_cast<int*>(ptr) = vp->value.toInt32(); return true; case QMetaType::UInt: - *reinterpret_cast<uint*>(ptr) = vp->toUInt32(); + *reinterpret_cast<uint*>(ptr) = vp->value.toUInt32(); return true; case QMetaType::LongLong: - *reinterpret_cast<qlonglong*>(ptr) = vp->toInteger(); + *reinterpret_cast<qlonglong*>(ptr) = vp->value.toInteger(); return true; case QMetaType::ULongLong: - *reinterpret_cast<qulonglong*>(ptr) = vp->toInteger(); + *reinterpret_cast<qulonglong*>(ptr) = vp->value.toInteger(); return true; case QMetaType::Double: - *reinterpret_cast<double*>(ptr) = vp->toNumber(); + *reinterpret_cast<double*>(ptr) = vp->value.toNumber(); return true; case QMetaType::QString: - *reinterpret_cast<QString*>(ptr) = vp->toString(); + *reinterpret_cast<QString*>(ptr) = vp->value.toString(engine->m_v4Engine->current)->toQString(); return true; case QMetaType::Float: - *reinterpret_cast<float*>(ptr) = vp->toNumber(); + *reinterpret_cast<float*>(ptr) = vp->value.toNumber(); return true; case QMetaType::Short: - *reinterpret_cast<short*>(ptr) = vp->toInt32(); + *reinterpret_cast<short*>(ptr) = vp->value.toInt32(); return true; case QMetaType::UShort: - *reinterpret_cast<unsigned short*>(ptr) = vp->toUInt16(); + *reinterpret_cast<unsigned short*>(ptr) = vp->value.toUInt16(); return true; case QMetaType::Char: - *reinterpret_cast<char*>(ptr) = vp->toInt32(); + *reinterpret_cast<char*>(ptr) = vp->value.toInt32(); return true; case QMetaType::UChar: - *reinterpret_cast<unsigned char*>(ptr) = vp->toUInt16(); + *reinterpret_cast<unsigned char*>(ptr) = vp->value.toUInt16(); return true; case QMetaType::QChar: - *reinterpret_cast<QChar*>(ptr) = vp->toUInt16(); + *reinterpret_cast<QChar*>(ptr) = vp->value.toUInt16(); return true; default: return false; diff --git a/src/qml/qml/v8/qjsvalue.cpp b/src/qml/qml/v8/qjsvalue.cpp index 87be773218..d74dfa8b21 100644 --- a/src/qml/qml/v8/qjsvalue.cpp +++ b/src/qml/qml/v8/qjsvalue.cpp @@ -39,14 +39,18 @@ ** ****************************************************************************/ -#include "qscriptisolate_p.h" +#include <QtCore/qstring.h> +#include <QtCore/qvarlengtharray.h> +#include <QtCore/qdatetime.h> #include "qjsengine.h" -#include "qv8engine_p.h" #include "qjsvalue.h" #include "qjsvalue_p.h" -#include "qscript_impl_p.h" -#include "qscriptshareddata_p.h" -#include <QtCore/qstring.h> +#include "qv4value_p.h" +#include "qv4object_p.h" +#include "qv4functionobject_p.h" +#include "qv4dateobject_p.h" +#include "qv4runtime_p.h" +#include "qv4v8_p.h" /*! \since 5.0 @@ -114,11 +118,18 @@ QT_BEGIN_NAMESPACE +using namespace QQmlJS::VM; + /*! Constructs a new QJSValue with a boolean \a value. */ QJSValue::QJSValue(bool value) - : d_ptr(new QJSValuePrivate(value)) + : d(new QJSValuePrivate(Value::fromBoolean(value))) +{ +} + +QJSValue::QJSValue(QJSValuePrivate *dd) + : d(dd) { } @@ -126,7 +137,7 @@ QJSValue::QJSValue(bool value) Constructs a new QJSValue with a number \a value. */ QJSValue::QJSValue(int value) - : d_ptr(new QJSValuePrivate(value)) + : d(new QJSValuePrivate(Value::fromInt32(value))) { } @@ -134,7 +145,7 @@ QJSValue::QJSValue(int value) Constructs a new QJSValue with a number \a value. */ QJSValue::QJSValue(uint value) - : d_ptr(new QJSValuePrivate(value)) + : d(new QJSValuePrivate(Value::fromUInt32(value))) { } @@ -142,7 +153,7 @@ QJSValue::QJSValue(uint value) Constructs a new QJSValue with a number \a value. */ QJSValue::QJSValue(double value) - : d_ptr(new QJSValuePrivate(value)) + : d(new QJSValuePrivate(Value::fromDouble(value))) { } @@ -150,7 +161,7 @@ QJSValue::QJSValue(double value) Constructs a new QJSValue with a string \a value. */ QJSValue::QJSValue(const QString& value) - : d_ptr(new QJSValuePrivate(value)) + : d(new QJSValuePrivate(value)) { } @@ -158,7 +169,7 @@ QJSValue::QJSValue(const QString& value) Constructs a new QJSValue with a special \a value. */ QJSValue::QJSValue(SpecialValue value) - : d_ptr(new QJSValuePrivate(value)) + : d(new QJSValuePrivate(value == UndefinedValue ? Value::undefinedValue() : Value::nullValue())) { } @@ -166,7 +177,7 @@ QJSValue::QJSValue(SpecialValue value) Constructs a new QJSValue with a string \a value. */ QJSValue::QJSValue(const QLatin1String &value) - : d_ptr(new QJSValuePrivate(value)) + : d(new QJSValuePrivate(value)) { } @@ -175,30 +186,12 @@ QJSValue::QJSValue(const QLatin1String &value) */ #ifndef QT_NO_CAST_FROM_ASCII QJSValue::QJSValue(const char *value) - : d_ptr(new QJSValuePrivate(QString::fromLatin1(value))) + : d(new QJSValuePrivate(QString::fromLatin1(value))) { } #endif /*! - Constructs a new QJSValue from private - \internal -*/ -QJSValue::QJSValue(QJSValuePrivate* d) - : d_ptr(d) -{ -} - -/*! - Constructs a new QJSValue from private - \internal -*/ -QJSValue::QJSValue(QScriptPassPointer<QJSValuePrivate> d) - : d_ptr(d.give()) -{ -} - -/*! Constructs a new QJSValue that is a copy of \a other. Note that if \a other is an object (i.e., isObject() would return @@ -206,8 +199,9 @@ QJSValue::QJSValue(QScriptPassPointer<QJSValuePrivate> d) the new script value (i.e., the object itself is not copied). */ QJSValue::QJSValue(const QJSValue& other) - : d_ptr(other.d_ptr) + : d(other.d) { + d->ref(); } /*! @@ -215,6 +209,7 @@ QJSValue::QJSValue(const QJSValue& other) */ QJSValue::~QJSValue() { + d->deref(); } /*! @@ -225,9 +220,7 @@ QJSValue::~QJSValue() */ bool QJSValue::isBool() const { - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->isBool(); + return d->value.isBoolean(); } /*! @@ -238,9 +231,7 @@ bool QJSValue::isBool() const */ bool QJSValue::isNumber() const { - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->isNumber(); + return d->value.isNumber(); } /*! @@ -249,9 +240,7 @@ bool QJSValue::isNumber() const */ bool QJSValue::isNull() const { - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->isNull(); + return d->value.isNull(); } /*! @@ -262,9 +251,7 @@ bool QJSValue::isNull() const */ bool QJSValue::isString() const { - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->isString(); + return d->value.isString(); } /*! @@ -273,9 +260,7 @@ bool QJSValue::isString() const */ bool QJSValue::isUndefined() const { - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->isUndefined(); + return d->value.isUndefined(); } /*! @@ -284,9 +269,8 @@ bool QJSValue::isUndefined() const */ bool QJSValue::isError() const { - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->isError(); + Object *o = d->value.asObject(); + return o && o->asErrorObject(); } /*! @@ -297,10 +281,8 @@ bool QJSValue::isError() const */ bool QJSValue::isArray() const { - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->isArray(); - } + return d->value.asArrayObject(); +} /*! Returns true if this QJSValue is of the Object type; otherwise @@ -313,9 +295,7 @@ bool QJSValue::isArray() const */ bool QJSValue::isObject() const { - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->isObject(); + return d->value.asObject(); } /*! @@ -326,9 +306,7 @@ bool QJSValue::isObject() const */ bool QJSValue::isCallable() const { - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->isCallable(); + return d->value.asFunctionObject(); } /*! @@ -339,9 +317,8 @@ bool QJSValue::isCallable() const */ bool QJSValue::isVariant() const { - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->isVariant(); + // ### + return false; } /*! @@ -358,9 +335,10 @@ bool QJSValue::isVariant() const */ QString QJSValue::toString() const { - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->toString(); + if (!d->engine) + // ### + return QString(); + return d->value.toString(d->engine->current)->toQString(); } /*! @@ -377,9 +355,7 @@ QString QJSValue::toString() const */ double QJSValue::toNumber() const { - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->toNumber(); + return d->value.toNumber(); } /*! @@ -396,9 +372,7 @@ double QJSValue::toNumber() const */ bool QJSValue::toBool() const { - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->toBool(); + return d->value.toBoolean(); } /*! @@ -415,9 +389,7 @@ bool QJSValue::toBool() const */ qint32 QJSValue::toInt() const { - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->toInt32(); + return d->value.toInt32(); } /*! @@ -434,9 +406,7 @@ qint32 QJSValue::toInt() const */ quint32 QJSValue::toUInt() const { - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->toUInt32(); + return d->value.toUInt32(); } /*! @@ -463,9 +433,8 @@ quint32 QJSValue::toUInt() const */ QVariant QJSValue::toVariant() const { - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->toVariant(); + // ### + return QVariant(); } /*! @@ -485,9 +454,25 @@ QVariant QJSValue::toVariant() const */ QJSValue QJSValue::call(const QJSValueList &args) { - Q_D(QJSValue); - QScriptIsolate api(d->engine()); - return d->call(/*thisObject=*/0, args); + FunctionObject *f = d->value.asFunctionObject(); + if (!f) + return QJSValue(); + + ExecutionEngine *engine = d->engine; + assert(engine); + + QVarLengthArray<Value> arguments(args.length()); + for (int i = 0; i < args.size(); ++i) + arguments[i] = args.at(i).d->getValue(engine); + + Value result; + try { + result = f->call(d->engine->current, Value::fromObject(d->engine->globalObject), arguments.data(), arguments.size()); + } catch (Exception &e) { + result = e.value(); + } + + return new QJSValuePrivate(engine, result); } /*! @@ -512,9 +497,25 @@ QJSValue QJSValue::call(const QJSValueList &args) */ QJSValue QJSValue::callWithInstance(const QJSValue &instance, const QJSValueList &args) { - Q_D(QJSValue); - QScriptIsolate api(d->engine()); - return d->call(QJSValuePrivate::get(instance), args); + FunctionObject *f = d->value.asFunctionObject(); + if (!f) + return QJSValue(); + + ExecutionEngine *engine = d->engine; + assert(engine); + + QVarLengthArray<Value> arguments(args.length()); + for (int i = 0; i < args.size(); ++i) + arguments[i] = args.at(i).d->getValue(engine); + + Value result; + try { + result = f->call(d->engine->current, instance.d->getValue(engine), arguments.data(), arguments.size()); + } catch (Exception &e) { + result = e.value(); + } + + return new QJSValuePrivate(engine, result); } /*! @@ -537,9 +538,25 @@ QJSValue QJSValue::callWithInstance(const QJSValue &instance, const QJSValueList */ QJSValue QJSValue::callAsConstructor(const QJSValueList &args) { - Q_D(QJSValue); - QScriptIsolate api(d->engine()); - return QJSValuePrivate::get(d->callAsConstructor(args)); + FunctionObject *f = d->value.asFunctionObject(); + if (!f) + return QJSValue(); + + ExecutionEngine *engine = d->engine; + assert(engine); + + QVarLengthArray<Value> arguments(args.length()); + for (int i = 0; i < args.size(); ++i) + arguments[i] = args.at(i).d->getValue(engine); + + Value result; + try { + result = f->construct(d->engine->current, arguments.data(), arguments.size()); + } catch (Exception &e) { + result = e.value(); + } + + return new QJSValuePrivate(engine, result); } #ifdef QT_DEPRECATED @@ -553,12 +570,8 @@ QJSValue QJSValue::callAsConstructor(const QJSValueList &args) */ QJSEngine* QJSValue::engine() const { - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - QV8Engine* engine = d->engine(); - if (engine) - return QV8Engine::get(engine); - return 0; + if (d->engine) + return d->engine->publicEngine; } #endif // QT_DEPRECATED @@ -572,9 +585,10 @@ QJSEngine* QJSValue::engine() const */ QJSValue QJSValue::prototype() const { - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return QJSValuePrivate::get(d->prototype()); + Object *o = d->value.asObject(); + if (!o) + return QJSValue(); + return new QJSValuePrivate(d->engine, Value::fromObject(o->prototype)); } /*! @@ -590,9 +604,13 @@ QJSValue QJSValue::prototype() const */ void QJSValue::setPrototype(const QJSValue& prototype) { - Q_D(QJSValue); - QScriptIsolate api(d->engine()); - d->setPrototype(QJSValuePrivate::get(prototype)); + Object *o = d->value.asObject(); + if (!o) + return; + Object *p = prototype.d->value.asObject(); + if (!p) + return; + o->prototype = p; } /*! @@ -604,8 +622,11 @@ void QJSValue::setPrototype(const QJSValue& prototype) */ QJSValue& QJSValue::operator=(const QJSValue& other) { - d_ptr = other.d_ptr; - return *this; + if (d == other.d) + return *this; + d->deref(); + d = other.d; + d->ref(); } /*! @@ -634,10 +655,7 @@ QJSValue& QJSValue::operator=(const QJSValue& other) */ bool QJSValue::equals(const QJSValue& other) const { - Q_D(const QJSValue); - QJSValuePrivate* otherValue = QJSValuePrivate::get(other); - QScriptIsolate api(d->engine() ? d->engine() : otherValue->engine()); - return d_ptr->equals(otherValue); + return __qmljs_equal(d->value, other.d->value); } /*! @@ -664,10 +682,7 @@ bool QJSValue::equals(const QJSValue& other) const */ bool QJSValue::strictlyEquals(const QJSValue& other) const { - Q_D(const QJSValue); - QJSValuePrivate* o = QJSValuePrivate::get(other); - QScriptIsolate api(d->engine() ? d->engine() : o->engine()); - return d_ptr->strictlyEquals(o); + return __qmljs_strict_equal(d->value, other.d->value); } /*! @@ -685,9 +700,13 @@ bool QJSValue::strictlyEquals(const QJSValue& other) const */ QJSValue QJSValue::property(const QString& name) const { - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return QJSValuePrivate::get(d->property(name)); + Object *o = d->value.asObject(); + if (!o) + return QJSValue(); + + String *s = d->engine->newIdentifier(name); + QQmlJS::VM::Value v = o->get(d->engine->current, s); + return new QJSValuePrivate(d->engine, v); } /*! @@ -704,9 +723,12 @@ QJSValue QJSValue::property(const QString& name) const */ QJSValue QJSValue::property(quint32 arrayIndex) const { - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return QJSValuePrivate::get(d->property(arrayIndex)); + Object *o = d->value.asObject(); + if (!o) + return QJSValue(); + + QQmlJS::VM::Value v = o->getIndexed(d->engine->current, arrayIndex); + return new QJSValuePrivate(d->engine, v); } /*! @@ -722,9 +744,12 @@ QJSValue QJSValue::property(quint32 arrayIndex) const */ void QJSValue::setProperty(const QString& name, const QJSValue& value) { - Q_D(QJSValue); - QScriptIsolate api(d->engine()); - d->setProperty(name, QJSValuePrivate::get(value)); + Object *o = d->value.asObject(); + if (!o) + return; + + String *s = d->engine->newIdentifier(name); + o->put(d->engine->current, s, value.d->value); } /*! @@ -741,9 +766,11 @@ void QJSValue::setProperty(const QString& name, const QJSValue& value) */ void QJSValue::setProperty(quint32 arrayIndex, const QJSValue& value) { - Q_D(QJSValue); - QScriptIsolate api(d->engine()); - d->setProperty(arrayIndex, QJSValuePrivate::get(value)); + Object *o = d->value.asObject(); + if (!o) + return; + + o->putIndexed(d->engine->current, arrayIndex, value.d->value); } /*! @@ -768,9 +795,12 @@ void QJSValue::setProperty(quint32 arrayIndex, const QJSValue& value) */ bool QJSValue::deleteProperty(const QString &name) { - Q_D(QJSValue); - QScriptIsolate api(d->engine()); - return d->deleteProperty(name); + Object *o = d->value.asObject(); + if (!o) + return false; + + String *s = d->engine->newIdentifier(name); + return o->deleteProperty(d->engine->current, s); } /*! @@ -781,9 +811,12 @@ bool QJSValue::deleteProperty(const QString &name) */ bool QJSValue::hasProperty(const QString &name) const { - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->hasProperty(name); + Object *o = d->value.asObject(); + if (!o) + return false; + + String *s = d->engine->newIdentifier(name); + return o->__hasProperty__(s); } /*! @@ -794,9 +827,12 @@ bool QJSValue::hasProperty(const QString &name) const */ bool QJSValue::hasOwnProperty(const QString &name) const { - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->hasOwnProperty(name); + Object *o = d->value.asObject(); + if (!o) + return false; + + String *s = d->engine->newIdentifier(name); + return o->__getOwnProperty__(s); } /*! @@ -811,9 +847,7 @@ bool QJSValue::hasOwnProperty(const QString &name) const */ QObject *QJSValue::toQObject() const { - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->toQObject(); + // ### } /*! @@ -825,9 +859,10 @@ QObject *QJSValue::toQObject() const */ QDateTime QJSValue::toDateTime() const { - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->toDataTime(); + QQmlJS::VM::DateObject *date = d->value.asDateObject(); + if (!date) + return QDateTime(); + return QQmlJS::VM::DatePrototype::toQDateTime(date->value.toNumber()); } /*! @@ -838,9 +873,7 @@ QDateTime QJSValue::toDateTime() const */ bool QJSValue::isDate() const { - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->isDate(); + return d->value.asDateObject(); } /*! @@ -849,9 +882,7 @@ bool QJSValue::isDate() const */ bool QJSValue::isRegExp() const { - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->isRegExp(); + return d->value.asRegExpObject(); } /*! @@ -865,9 +896,7 @@ bool QJSValue::isRegExp() const */ bool QJSValue::isQObject() const { - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->isQObject(); + // ### } /*! @@ -893,7 +922,7 @@ bool QJSValue::isQObject() const Q_QML_EXPORT v8::Local<v8::Value> qt_QJSValueV8Value(const QJSValue &value) { QJSValuePrivate *d = QJSValuePrivate::get(value); - return v8::Local<v8::Value>::New(d->handle()); + return v8::Local<v8::Value>::New(v8::Value::fromVmValue(d->value)); } QT_END_NAMESPACE diff --git a/src/qml/qml/v8/qjsvalue.h b/src/qml/qml/v8/qjsvalue.h index efd52ce880..cf02ad819e 100644 --- a/src/qml/qml/v8/qjsvalue.h +++ b/src/qml/qml/v8/qjsvalue.h @@ -45,8 +45,7 @@ #include <QtQml/qtqmlglobal.h> #include <QtCore/qstring.h> #include <QtCore/qlist.h> -#include <QtCore/qsharedpointer.h> -#include <QtCore/qshareddata.h> +#include <QtCore/qmetatype.h> QT_BEGIN_NAMESPACE @@ -59,10 +58,7 @@ struct QMetaObject; class QDateTime; typedef QList<QJSValue> QJSValueList; - class QJSValuePrivate; -struct QScriptValuePrivatePointerDeleter; -template <class T> class QScriptPassPointer; class Q_QML_EXPORT QJSValue { @@ -137,18 +133,13 @@ public: QT_DEPRECATED QJSEngine *engine() const; #endif + QJSValue(QJSValuePrivate *dd); private: + friend class QJSValuePrivate; // force compile error, prevent QJSValue(bool) to be called - QJSValue(void *) Q_DECL_EQ_DELETE; - QJSValue(QJSValuePrivate*); - QJSValue(QScriptPassPointer<QJSValuePrivate>); - -private: - QExplicitlySharedDataPointer<QJSValuePrivate> d_ptr; - - Q_DECLARE_PRIVATE(QJSValue) + QJSValuePrivate *d; }; QT_END_NAMESPACE diff --git a/src/qml/qml/v8/qjsvalue_impl_p.h b/src/qml/qml/v8/qjsvalue_impl_p.h deleted file mode 100644 index b124c60cc8..0000000000 --- a/src/qml/qml/v8/qjsvalue_impl_p.h +++ /dev/null @@ -1,950 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -// -// 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. -// - -#ifndef QJSVALUE_IMPL_P_H -#define QJSVALUE_IMPL_P_H - -#include "qjsconverter_p.h" -#include "qjsvalue_p.h" -#include "qv8engine_p.h" -#include "qscriptisolate_p.h" - -QT_BEGIN_NAMESPACE - -QJSValuePrivate* QJSValuePrivate::get(const QJSValue& q) { Q_ASSERT(q.d_ptr.data()); return q.d_ptr.data(); } - -QJSValue QJSValuePrivate::get(const QJSValuePrivate* d) -{ - Q_ASSERT(d); - return QJSValue(const_cast<QJSValuePrivate*>(d)); -} - -QJSValue QJSValuePrivate::get(QScriptPassPointer<QJSValuePrivate> d) -{ - Q_ASSERT(d); - return QJSValue(d); -} - -QJSValue QJSValuePrivate::get(QJSValuePrivate* d) -{ - Q_ASSERT(d); - return QJSValue(d); -} - -QJSValuePrivate::QJSValuePrivate(bool value) - : m_engine(0), m_state(CBool), u(value) -{ -} - -QJSValuePrivate::QJSValuePrivate(int value) - : m_engine(0), m_state(CNumber), u(value) -{ -} - -QJSValuePrivate::QJSValuePrivate(uint value) - : m_engine(0), m_state(CNumber), u(value) -{ -} - -QJSValuePrivate::QJSValuePrivate(double value) - : m_engine(0), m_state(CNumber), u(value) -{ -} - -QJSValuePrivate::QJSValuePrivate(const QString& value) - : m_engine(0), m_state(CString), u(new QString(value)) -{ -} - -QJSValuePrivate::QJSValuePrivate(QJSValue::SpecialValue value) - : m_engine(0), m_state(value == QJSValue::NullValue ? CNull : CUndefined) -{ -} - -QJSValuePrivate::QJSValuePrivate(QV8Engine* engine, bool value) - : m_engine(engine), m_state(JSValue) -{ - Q_ASSERT(engine); - v8::HandleScope handleScope; - m_value = v8::Persistent<v8::Value>::New(m_engine->makeJSValue(value)); - m_engine->registerValue(this); -} - -QJSValuePrivate::QJSValuePrivate(QV8Engine* engine, int value) - : m_engine(engine), m_state(JSValue) -{ - Q_ASSERT(engine); - v8::HandleScope handleScope; - m_value = v8::Persistent<v8::Value>::New(m_engine->makeJSValue(value)); - m_engine->registerValue(this); -} - -QJSValuePrivate::QJSValuePrivate(QV8Engine* engine, uint value) - : m_engine(engine), m_state(JSValue) -{ - Q_ASSERT(engine); - v8::HandleScope handleScope; - m_value = v8::Persistent<v8::Value>::New(m_engine->makeJSValue(value)); - m_engine->registerValue(this); -} - -QJSValuePrivate::QJSValuePrivate(QV8Engine* engine, double value) - : m_engine(engine), m_state(JSValue) -{ - Q_ASSERT(engine); - v8::HandleScope handleScope; - m_value = v8::Persistent<v8::Value>::New(m_engine->makeJSValue(value)); - m_engine->registerValue(this); -} - -QJSValuePrivate::QJSValuePrivate(QV8Engine* engine, const QString& value) - : m_engine(engine), m_state(JSValue) -{ - Q_ASSERT(engine); - v8::HandleScope handleScope; - m_value = v8::Persistent<v8::Value>::New(m_engine->makeJSValue(value)); - m_engine->registerValue(this); -} - -QJSValuePrivate::QJSValuePrivate(QV8Engine* engine, QJSValue::SpecialValue value) - : m_engine(engine), m_state(JSValue) -{ - Q_ASSERT(engine); - v8::HandleScope handleScope; - m_value = v8::Persistent<v8::Value>::New(m_engine->makeJSValue(value)); - m_engine->registerValue(this); -} - -QJSValuePrivate::QJSValuePrivate(QV8Engine *engine, v8::Handle<v8::Value> value) - : m_engine(engine), m_state(JSValue), m_value(v8::Persistent<v8::Value>::New(value)) -{ - Q_ASSERT(engine); - // It shouldn't happen, v8 shows errors by returning an empty handler. This is important debug - // information and it can't be simply ignored. - Q_ASSERT(!value.IsEmpty()); - m_engine->registerValue(this); -} - -QJSValuePrivate::~QJSValuePrivate() -{ - if (isJSBased()) { - m_engine->unregisterValue(this); - QScriptIsolate api(m_engine); - m_value.Dispose(); - } else if (isStringBased()) { - delete u.m_string; - } -} - -bool QJSValuePrivate::toBool() const -{ - switch (m_state) { - case JSValue: - { - v8::HandleScope scope; - return m_value->ToBoolean()->Value(); - } - case CNumber: - return !(qIsNaN(u.m_number) || !u.m_number); - case CBool: - return u.m_bool; - case CNull: - case CUndefined: - return false; - case CString: - return u.m_string->length(); - } - - Q_ASSERT_X(false, "toBool()", "Not all states are included in the previous switch statement."); - return false; // Avoid compiler warning. -} - -double QJSValuePrivate::toNumber() const -{ - switch (m_state) { - case JSValue: - { - v8::HandleScope scope; - return m_value->ToNumber()->Value(); - } - case CNumber: - return u.m_number; - case CBool: - return u.m_bool ? 1 : 0; - case CNull: - case CUndefined: - return qQNaN(); - case CString: - bool ok; - double result = u.m_string->toDouble(&ok); - if (ok) - return result; - result = u.m_string->toInt(&ok, 0); // Try other bases. - if (ok) - return result; - if (*u.m_string == QLatin1String("Infinity")) - return qInf(); - if (*u.m_string == QLatin1String("-Infinity")) - return -qInf(); - return u.m_string->length() ? qQNaN() : 0; - } - - Q_ASSERT_X(false, "toNumber()", "Not all states are included in the previous switch statement."); - return 0; // Avoid compiler warning. -} - -QString QJSValuePrivate::toString() const -{ - switch (m_state) { - case CBool: - return u.m_bool ? QString::fromLatin1("true") : QString::fromLatin1("false"); - case CString: - return *u.m_string; - case CNumber: - return QJSConverter::toString(u.m_number); - case CNull: - return QString::fromLatin1("null"); - case CUndefined: - return QString::fromLatin1("undefined"); - case JSValue: - Q_ASSERT(!m_value.IsEmpty()); - v8::HandleScope handleScope; - v8::TryCatch tryCatch; - v8::Local<v8::String> result = m_value->ToString(); - if (result.IsEmpty()) - result = tryCatch.Exception()->ToString(); - return QJSConverter::toString(result); - } - - Q_ASSERT_X(false, "toString()", "Not all states are included in the previous switch statement."); - return QString(); // Avoid compiler warning. -} - -QVariant QJSValuePrivate::toVariant() const -{ - switch (m_state) { - case CBool: - return QVariant(u.m_bool); - case CString: - return QVariant(*u.m_string); - case CNumber: - return QVariant(u.m_number); - case CNull: - return QVariant(QMetaType::VoidStar, 0); - case CUndefined: - return QVariant(); - case JSValue: - break; - } - - Q_ASSERT(m_state == JSValue); - Q_ASSERT(!m_value.IsEmpty()); - Q_ASSERT(m_engine); - - v8::HandleScope handleScope; - return m_engine->variantFromJS(m_value); -} - -inline QDateTime QJSValuePrivate::toDataTime() const -{ - if (!isDate()) - return QDateTime(); - - v8::HandleScope handleScope; - return QJSConverter::toDateTime(v8::Handle<v8::Date>::Cast(m_value)); - -} - -QObject* QJSValuePrivate::toQObject() const -{ - if (!isJSBased()) - return 0; - - v8::HandleScope handleScope; - return engine()->qtObjectFromJS(m_value); -} - -double QJSValuePrivate::toInteger() const -{ - double result = toNumber(); - if (qIsNaN(result)) - return 0; - if (qIsInf(result)) - return result; - - // Must use floor explicitly rather than qFloor here. On some - // platforms qFloor will cast the value to a single precision float and use - // floorf() which results in test failures. - return (result > 0) ? floor(result) : -1 * floor(-result); -} - -qint32 QJSValuePrivate::toInt32() const -{ - double result = toInteger(); - // Orginaly it should look like that (result == 0 || qIsInf(result) || qIsNaN(result)), but - // some of these operation are invoked in toInteger subcall. - if (qIsInf(result)) - return 0; - return result; -} - -quint32 QJSValuePrivate::toUInt32() const -{ - double result = toInteger(); - // Orginaly it should look like that (result == 0 || qIsInf(result) || qIsNaN(result)), but - // some of these operation are invoked in toInteger subcall. - if (qIsInf(result)) - return 0; - - // The explicit casts are required to avoid undefined behaviour. For example, casting - // a negative double directly to an unsigned int on ARM NEON FPU results in the value - // being set to zero. Casting to a signed int first ensures well defined behaviour. - return (quint32) (qint32) result; -} - -quint16 QJSValuePrivate::toUInt16() const -{ - return toInt32(); -} - -inline bool QJSValuePrivate::isArray() const -{ - return isJSBased() && m_value->IsArray(); -} - -inline bool QJSValuePrivate::isBool() const -{ - return m_state == CBool || (isJSBased() && m_value->IsBoolean()); -} - -inline bool QJSValuePrivate::isCallable() const -{ - if (isFunction()) - return true; - if (isObject()) { - // Our C++ wrappers register function handlers but not always act as callables. - return v8::Object::Cast(m_value.get())->IsCallable(); - } - return false; -} - -inline bool QJSValuePrivate::isError() const -{ - if (!isJSBased()) - return false; - v8::HandleScope handleScope; - return m_value->IsError(); -} - -inline bool QJSValuePrivate::isFunction() const -{ - return isJSBased() && m_value->IsFunction(); -} - -inline bool QJSValuePrivate::isNull() const -{ - return m_state == CNull || (isJSBased() && m_value->IsNull()); -} - -inline bool QJSValuePrivate::isNumber() const -{ - return m_state == CNumber || (isJSBased() && m_value->IsNumber()); -} - -inline bool QJSValuePrivate::isObject() const -{ - return isJSBased() && m_value->IsObject(); -} - -inline bool QJSValuePrivate::isString() const -{ - return m_state == CString || (isJSBased() && m_value->IsString()); -} - -inline bool QJSValuePrivate::isUndefined() const -{ - return m_state == CUndefined || (isJSBased() && m_value->IsUndefined()); -} - -inline bool QJSValuePrivate::isVariant() const -{ - return isJSBased() && m_engine->isVariant(m_value); -} - -bool QJSValuePrivate::isDate() const -{ - return (isJSBased() && m_value->IsDate()); -} - -bool QJSValuePrivate::isRegExp() const -{ - return (isJSBased() && m_value->IsRegExp()); -} - -bool QJSValuePrivate::isQObject() const -{ - return isJSBased() && engine()->isQObject(m_value); -} - -inline bool QJSValuePrivate::equals(QJSValuePrivate* other) -{ - if (!isJSBased() && !other->isJSBased()) { - switch (m_state) { - case CNull: - case CUndefined: - return other->isUndefined() || other->isNull(); - case CNumber: - switch (other->m_state) { - case CBool: - case CString: - return u.m_number == other->toNumber(); - case CNumber: - return u.m_number == other->u.m_number; - default: - return false; - } - case CBool: - switch (other->m_state) { - case CBool: - return u.m_bool == other->u.m_bool; - case CNumber: - return toNumber() == other->u.m_number; - case CString: - return toNumber() == other->toNumber(); - default: - return false; - } - case CString: - switch (other->m_state) { - case CBool: - return toNumber() == other->toNumber(); - case CNumber: - return toNumber() == other->u.m_number; - case CString: - return *u.m_string == *other->u.m_string; - default: - return false; - } - default: - Q_ASSERT_X(false, "QJSValue::equals", "Not all states are included in the previous switch statement."); - } - } - - v8::HandleScope handleScope; - if (isJSBased() && !other->isJSBased()) { - if (!other->assignEngine(engine())) { - qWarning("QJSValue::equals: cannot compare to a value created in a different engine"); - return false; - } - } else if (!isJSBased() && other->isJSBased()) { - if (!assignEngine(other->engine())) { - qWarning("QJSValue::equals: cannot compare to a value created in a different engine"); - return false; - } - } - - Q_ASSERT(this->engine() && other->engine()); - if (this->engine() != other->engine()) { - qWarning("QJSValue::equals: cannot compare to a value created in a different engine"); - return false; - } - return m_value->Equals(other->m_value); -} - -inline bool QJSValuePrivate::strictlyEquals(QJSValuePrivate* other) -{ - if (isJSBased()) { - // We can't compare these two values without binding to the same engine. - if (!other->isJSBased()) { - if (other->assignEngine(engine())) - return m_value->StrictEquals(other->m_value); - return false; - } - if (other->engine() != engine()) { - qWarning("QJSValue::strictlyEquals: cannot compare to a value created in a different engine"); - return false; - } - return m_value->StrictEquals(other->m_value); - } - if (isStringBased()) { - if (other->isStringBased()) - return *u.m_string == *(other->u.m_string); - if (other->isJSBased()) { - assignEngine(other->engine()); - return m_value->StrictEquals(other->m_value); - } - } - if (isNumberBased()) { - if (other->isJSBased()) { - assignEngine(other->engine()); - return m_value->StrictEquals(other->m_value); - } - if (m_state != other->m_state) - return false; - if (m_state == CNumber) - return u.m_number == other->u.m_number; - Q_ASSERT(m_state == CBool); - return u.m_bool == other->u.m_bool; - } - - return (isUndefined() && other->isUndefined()) - || (isNull() && other->isNull()); -} - -inline QScriptPassPointer<QJSValuePrivate> QJSValuePrivate::prototype() const -{ - if (isObject()) { - v8::HandleScope handleScope; - return new QJSValuePrivate(engine(), v8::Handle<v8::Object>::Cast(m_value)->GetPrototype()); - } - return new QJSValuePrivate(); -} - -inline void QJSValuePrivate::setPrototype(QJSValuePrivate* prototype) -{ - if (isObject() && (prototype->isObject() || prototype->isNull())) { - if (engine() != prototype->engine()) { - if (prototype->engine()) { - qWarning("QJSValue::setPrototype() failed: cannot set a prototype created in a different engine"); - return; - } - prototype->assignEngine(engine()); - } - v8::HandleScope handleScope; - if (!v8::Handle<v8::Object>::Cast(m_value)->SetPrototype(*prototype)) - qWarning("QJSValue::setPrototype() failed: cyclic prototype value"); - } -} - -inline void QJSValuePrivate::setProperty(const QString& name, QJSValuePrivate* value, uint attribs) -{ - if (!isObject()) - return; - v8::HandleScope handleScope; - setProperty(QJSConverter::toString(name), value, attribs); -} - -inline void QJSValuePrivate::setProperty(v8::Handle<v8::String> name, QJSValuePrivate* value, uint attribs) -{ - if (!isObject()) - return; - - if (!value->isJSBased()) - value->assignEngine(engine()); - - if (engine() != value->engine()) { - qWarning("QJSValue::setProperty(%s) failed: " - "cannot set value created in a different engine", - qPrintable(QJSConverter::toString(name))); - return; - } - - v8::TryCatch tryCatch; -// if (attribs & (QJSValue::PropertyGetter | QJSValue::PropertySetter)) { -// engine()->originalGlobalObject()->defineGetterOrSetter(*this, name, value->m_value, attribs); -// } else { - v8::Object::Cast(m_value.get())->Set(name, value->m_value, v8::PropertyAttribute(attribs & QJSConverter::PropertyAttributeMask)); -// } -} - -inline void QJSValuePrivate::setProperty(quint32 index, QJSValuePrivate* value, uint attribs) -{ - // FIXME this method should by integrated with other overloads to use the same code patch. - // for now it is not possible as v8 doesn't allow to set property attributes using index based api. - - if (!isObject()) - return; - - if (attribs) { - // FIXME we don't need to convert index to a string. - //Object::Set(int,value) do not take attributes. - setProperty(QString::number(index), value, attribs); - return; - } - - if (!value->isJSBased()) - value->assignEngine(engine()); - - if (engine() != value->engine()) { - qWarning("QJSValue::setProperty() failed: cannot set value created in a different engine"); - return; - } - - v8::HandleScope handleScope; - v8::Object::Cast(m_value.get())->Set(index, value->m_value); -} - -inline QScriptPassPointer<QJSValuePrivate> QJSValuePrivate::property(const QString& name) const -{ - if (!isObject()) - return new QJSValuePrivate(); - if (!name.length()) - return new QJSValuePrivate(engine()); - - v8::HandleScope handleScope; - return property(QJSConverter::toString(name)); -} - -inline QScriptPassPointer<QJSValuePrivate> QJSValuePrivate::property(v8::Handle<v8::String> name) const -{ - Q_ASSERT(!name.IsEmpty()); - if (!isObject()) - return new QJSValuePrivate(); - return property<>(name); -} - -inline QScriptPassPointer<QJSValuePrivate> QJSValuePrivate::property(quint32 index) const -{ - if (!isObject()) - return new QJSValuePrivate(); - return property<>(index); -} - -template<typename T> -inline QScriptPassPointer<QJSValuePrivate> QJSValuePrivate::property(T name) const -{ - Q_ASSERT(isObject()); - v8::HandleScope handleScope; - v8::Handle<v8::Object> self(v8::Object::Cast(m_value.get())); - - v8::TryCatch tryCatch; - v8::Handle<v8::Value> result = self->Get(name); - if (tryCatch.HasCaught()) - result = tryCatch.Exception(); - if (result.IsEmpty()) - return new QJSValuePrivate(engine()); - return new QJSValuePrivate(engine(), result); -} - -inline bool QJSValuePrivate::deleteProperty(const QString& name) -{ - if (!isObject()) - return false; - - v8::HandleScope handleScope; - v8::Handle<v8::Object> self(v8::Handle<v8::Object>::Cast(m_value)); - return self->Delete(QJSConverter::toString(name)); -} - -inline bool QJSValuePrivate::hasProperty(const QString &name) const -{ - if (!isObject()) - return false; - - v8::HandleScope handleScope; - v8::Handle<v8::Object> self(v8::Handle<v8::Object>::Cast(m_value)); - return self->Has(QJSConverter::toString(name)); -} - -inline bool QJSValuePrivate::hasOwnProperty(const QString &name) const -{ - if (!isObject()) - return false; - - v8::HandleScope handleScope; - v8::Handle<v8::Object> self(v8::Handle<v8::Object>::Cast(m_value)); - return self->HasOwnProperty(QJSConverter::toString(name)); -} - -inline QJSValuePrivate::PropertyFlags QJSValuePrivate::propertyFlags(const QString& name) const -{ - if (!isObject()) - return QJSValuePrivate::PropertyFlags(0); - - v8::HandleScope handleScope; - return engine()->getPropertyFlags(v8::Handle<v8::Object>::Cast(m_value), QJSConverter::toString(name)); -} - -inline QJSValuePrivate::PropertyFlags QJSValuePrivate::propertyFlags(v8::Handle<v8::String> name) const -{ - if (!isObject()) - return QJSValuePrivate::PropertyFlags(0); - - v8::HandleScope handleScope; - return engine()->getPropertyFlags(v8::Handle<v8::Object>::Cast(m_value), name); -} - -inline QScriptPassPointer<QJSValuePrivate> QJSValuePrivate::call(QJSValuePrivate* thisObject, const QJSValueList& args) -{ - if (!isCallable()) - return new QJSValuePrivate(); - - v8::HandleScope handleScope; - - // Convert all arguments and bind to the engine. - int argc = args.size(); - QVarLengthArray<v8::Handle<v8::Value>, 8> argv(argc); - if (!prepareArgumentsForCall(argv.data(), args)) { - qWarning("QJSValue::call() failed: cannot call function with argument created in a different engine"); - return new QJSValuePrivate(engine()); - } - - return call(thisObject, argc, argv.data()); -} - -QScriptPassPointer<QJSValuePrivate> QJSValuePrivate::call(QJSValuePrivate* thisObject, int argc, v8::Handle<v8::Value> *argv) -{ - QV8Engine *e = engine(); - - v8::Handle<v8::Object> recv; - - if (!thisObject || !thisObject->isObject()) { - recv = v8::Handle<v8::Object>(v8::Object::Cast(e->global().get())); - } else { - if (!thisObject->assignEngine(e)) { - qWarning("QJSValue::call() failed: cannot call function with thisObject created in a different engine"); - return new QJSValuePrivate(engine()); - } - - recv = v8::Handle<v8::Object>(v8::Object::Cast(thisObject->m_value.get())); - } - - if (argc < 0) { - v8::Local<v8::Value> exeption = v8::Exception::TypeError(v8::String::New("Arguments must be an array")); - return new QJSValuePrivate(e, exeption); - } - - v8::TryCatch tryCatch; - v8::Handle<v8::Value> result = v8::Object::Cast(m_value.get())->CallAsFunction(recv, argc, argv); - - if (result.IsEmpty()) { - result = tryCatch.Exception(); - // TODO: figure out why v8 doesn't always produce an exception value. - //Q_ASSERT(!result.IsEmpty()); - if (result.IsEmpty()) - result = v8::Exception::Error(v8::String::New("missing exception value")); - } - - return new QJSValuePrivate(e, result); -} - -inline QScriptPassPointer<QJSValuePrivate> QJSValuePrivate::callAsConstructor(int argc, v8::Handle<v8::Value> *argv) -{ - QV8Engine *e = engine(); - - if (argc < 0) { - v8::Local<v8::Value> exeption = v8::Exception::TypeError(v8::String::New("Arguments must be an array")); - return new QJSValuePrivate(e, exeption); - } - - v8::TryCatch tryCatch; - v8::Handle<v8::Value> result = v8::Object::Cast(m_value.get())->CallAsConstructor(argc, argv); - - if (result.IsEmpty()) - result = tryCatch.Exception(); - - return new QJSValuePrivate(e, result); -} - -inline QScriptPassPointer<QJSValuePrivate> QJSValuePrivate::callAsConstructor(const QJSValueList& args) -{ - if (!isCallable()) - return new QJSValuePrivate(); - - v8::HandleScope handleScope; - - // Convert all arguments and bind to the engine. - int argc = args.size(); - QVarLengthArray<v8::Handle<v8::Value>, 8> argv(argc); - if (!prepareArgumentsForCall(argv.data(), args)) { - qWarning("QJSValue::callAsConstructor() failed: cannot construct function with argument created in a different engine"); - return new QJSValuePrivate(engine()); - } - - return callAsConstructor(argc, argv.data()); -} - -/*! \internal - * Make sure this value is associated with a v8 value belonging to this engine. - * If the value belongs to another engine, returns false. - */ -bool QJSValuePrivate::assignEngine(QV8Engine* engine) -{ - Q_ASSERT(engine); - v8::HandleScope handleScope; - switch (m_state) { - case CBool: - m_value = v8::Persistent<v8::Value>::New(engine->makeJSValue(u.m_bool)); - break; - case CString: - m_value = v8::Persistent<v8::Value>::New(engine->makeJSValue(*u.m_string)); - delete u.m_string; - break; - case CNumber: - m_value = v8::Persistent<v8::Value>::New(engine->makeJSValue(u.m_number)); - break; - case CNull: - m_value = v8::Persistent<v8::Value>::New(engine->makeJSValue(QJSValue::NullValue)); - break; - case CUndefined: - m_value = v8::Persistent<v8::Value>::New(engine->makeJSValue(QJSValue::UndefinedValue)); - break; - default: - if (this->engine() == engine) - return true; - else if (!isJSBased()) - Q_ASSERT_X(!isJSBased(), "assignEngine()", "Not all states are included in the previous switch statement."); - else - qWarning("JSValue can't be rassigned to an another engine."); - return false; - } - m_engine = engine; - m_state = JSValue; - - m_engine->registerValue(this); - return true; -} - -/*! - \internal - Invalidates this value (makes it undefined). - - Does not remove the value from the engine's list of - registered values; that's the responsibility of the caller. -*/ -void QJSValuePrivate::invalidate() -{ - if (isJSBased()) { - m_value.Dispose(); - m_value.Clear(); - } else if (isStringBased()) { - delete u.m_string; - } - m_engine = 0; - m_state = CUndefined; -} - -QV8Engine* QJSValuePrivate::engine() const -{ - return m_engine; -} - -inline QJSValuePrivate::operator v8::Handle<v8::Value>() const -{ - Q_ASSERT(isJSBased()); - return m_value; -} - -inline QJSValuePrivate::operator v8::Handle<v8::Object>() const -{ - Q_ASSERT(isObject()); - return v8::Handle<v8::Object>::Cast(m_value); -} - -inline v8::Handle<v8::Value> QJSValuePrivate::handle() const -{ - return m_value; -} - -/*! - * Return a v8::Handle, assign to the engine if needed. - */ -v8::Handle<v8::Value> QJSValuePrivate::asV8Value(QV8Engine* engine) -{ - if (!m_engine) { - if (!assignEngine(engine)) - return v8::Handle<v8::Value>(); - } - Q_ASSERT(isJSBased()); - return m_value; -} - -/*! - \internal - Returns true if QSV have an engine associated. -*/ -bool QJSValuePrivate::isJSBased() const -{ -#ifndef QT_NO_DEBUG - // internals check. - if (m_state >= JSValue) - Q_ASSERT(!m_value.IsEmpty()); - else - Q_ASSERT(m_value.IsEmpty()); -#endif - return m_state >= JSValue; -} - -/*! - \internal - Returns true if current value of QSV is placed in m_number. -*/ -bool QJSValuePrivate::isNumberBased() const { return m_state == CNumber || m_state == CBool; } - -/*! - \internal - Returns true if current value of QSV is placed in m_string. -*/ -bool QJSValuePrivate::isStringBased() const { return m_state == CString; } - -/*! - \internal - Converts arguments and bind them to the engine. - \attention argv should be big enough -*/ -inline bool QJSValuePrivate::prepareArgumentsForCall(v8::Handle<v8::Value> argv[], const QJSValueList& args) const -{ - QJSValueList::const_iterator i = args.constBegin(); - for (int j = 0; i != args.constEnd(); j++, i++) { - QJSValuePrivate* value = QJSValuePrivate::get(*i); - if ((value->isJSBased() && engine() != value->engine()) - || (!value->isJSBased() && !value->assignEngine(engine()))) - // Different engines are not allowed! - return false; - argv[j] = *value; - } - return true; -} - -QT_END_NAMESPACE - -#endif diff --git a/src/qml/qml/v8/qjsvalue_p.h b/src/qml/qml/v8/qjsvalue_p.h index c4c8d415d4..2bc9ec7eb1 100644 --- a/src/qml/qml/v8/qjsvalue_p.h +++ b/src/qml/qml/v8/qjsvalue_p.h @@ -53,161 +53,48 @@ #ifndef QJSVALUE_P_H #define QJSVALUE_P_H -#include <private/qv8_p.h> - -#include <QtCore/qbytearray.h> -#include <QtCore/qdatetime.h> -#include <QtCore/qmath.h> -#include <QtCore/qvarlengtharray.h> -#include <qdebug.h> - -#include <private/qintrusivelist_p.h> -#include "qscriptshareddata_p.h" -#include "qjsvalue.h" +#include <qjsvalue.h> +#include <private/qv4value_p.h> +#include <private/qv4string_p.h> +#include <private/qv4engine_p.h> QT_BEGIN_NAMESPACE -class QV8Engine; - /*! \internal \class QJSValuePrivate */ -class QJSValuePrivate - : public QSharedData +class QJSValuePrivate : public QQmlJS::VM::PersistentValuePrivate { public: - enum PropertyFlag { - ReadOnly = 0x00000001, - Undeletable = 0x00000002, - SkipInEnumeration = 0x00000004 - }; - Q_DECLARE_FLAGS(PropertyFlags, PropertyFlag) - - inline static QJSValuePrivate* get(const QJSValue& q); - inline static QJSValue get(const QJSValuePrivate* d); - inline static QJSValue get(QJSValuePrivate* d); - inline static QJSValue get(QScriptPassPointer<QJSValuePrivate> d); - inline ~QJSValuePrivate(); - - inline QJSValuePrivate(bool value); - inline QJSValuePrivate(int value); - inline QJSValuePrivate(uint value); - inline QJSValuePrivate(double value); - inline QJSValuePrivate(const QString& value); - inline QJSValuePrivate(QJSValue::SpecialValue value = QJSValue::UndefinedValue); - - inline QJSValuePrivate(QV8Engine *engine, bool value); - inline QJSValuePrivate(QV8Engine *engine, int value); - inline QJSValuePrivate(QV8Engine *engine, uint value); - inline QJSValuePrivate(QV8Engine *engine, double value); - inline QJSValuePrivate(QV8Engine *engine, const QString& value); - inline QJSValuePrivate(QV8Engine *engine, QJSValue::SpecialValue value = QJSValue::UndefinedValue); - inline QJSValuePrivate(QV8Engine *engine, v8::Handle<v8::Value>); - inline void invalidate(); - - inline bool toBool() const; - inline double toNumber() const; - inline QString toString() const; - inline double toInteger() const; - inline qint32 toInt32() const; - inline quint32 toUInt32() const; - inline quint16 toUInt16() const; - inline QDateTime toDataTime() const; - inline QObject *toQObject() const; - inline QVariant toVariant() const; - - inline bool isArray() const; - inline bool isBool() const; - inline bool isCallable() const; - inline bool isError() const; - inline bool isFunction() const; - inline bool isNull() const; - inline bool isNumber() const; - inline bool isObject() const; - inline bool isString() const; - inline bool isUndefined() const; - inline bool isVariant() const; - inline bool isDate() const; - inline bool isRegExp() const; - inline bool isQObject() const; - - inline bool equals(QJSValuePrivate* other); - inline bool strictlyEquals(QJSValuePrivate* other); - - inline QScriptPassPointer<QJSValuePrivate> prototype() const; - inline void setPrototype(QJSValuePrivate* prototype); - - inline void setProperty(const QString &name, QJSValuePrivate *value, uint attribs = 0); - inline void setProperty(v8::Handle<v8::String> name, QJSValuePrivate *value, uint attribs = 0); - inline void setProperty(quint32 index, QJSValuePrivate* value, uint attribs = 0); - inline QScriptPassPointer<QJSValuePrivate> property(const QString& name) const; - inline QScriptPassPointer<QJSValuePrivate> property(v8::Handle<v8::String> name) const; - inline QScriptPassPointer<QJSValuePrivate> property(quint32 index) const; - template<typename T> - inline QScriptPassPointer<QJSValuePrivate> property(T name) const; - inline bool deleteProperty(const QString& name); - inline bool hasProperty(const QString &name) const; - inline bool hasOwnProperty(const QString &name) const; - inline PropertyFlags propertyFlags(const QString& name) const; - inline PropertyFlags propertyFlags(v8::Handle<v8::String> name) const; - - inline QScriptPassPointer<QJSValuePrivate> call(QJSValuePrivate* thisObject, const QJSValueList& args); - inline QScriptPassPointer<QJSValuePrivate> call(QJSValuePrivate* thisObject, const QJSValue& arguments); - inline QScriptPassPointer<QJSValuePrivate> call(QJSValuePrivate* thisObject, int argc, v8::Handle< v8::Value >* argv); - inline QScriptPassPointer<QJSValuePrivate> callAsConstructor(int argc, v8::Handle<v8::Value> *argv); - inline QScriptPassPointer<QJSValuePrivate> callAsConstructor(const QJSValueList& args); - inline QScriptPassPointer<QJSValuePrivate> callAsConstructor(const QJSValue& arguments); - - inline bool assignEngine(QV8Engine *engine); - inline QV8Engine *engine() const; - - inline operator v8::Handle<v8::Value>() const; - inline operator v8::Handle<v8::Object>() const; - inline v8::Handle<v8::Value> handle() const; - inline v8::Handle<v8::Value> asV8Value(QV8Engine *engine); -private: - QIntrusiveListNode m_node; - QV8Engine *m_engine; - - // Please, update class documentation when you change the enum. - enum State { - CString = 0x1000, - CNumber, - CBool, - CNull, - CUndefined, - JSValue = 0x2000 // V8 values are equal or higher then this value. - // JSPrimitive, - // JSObject - } m_state; - - union CValue { - bool m_bool; - double m_number; - QString* m_string; - - CValue() : m_number(0) {} - CValue(bool value) : m_bool(value) {} - CValue(int number) : m_number(number) {} - CValue(uint number) : m_number(number) {} - CValue(double number) : m_number(number) {} - CValue(QString* string) : m_string(string) {} - } u; - // v8::Persistent is not a POD, so can't be part of the union. - v8::Persistent<v8::Value> m_value; - - Q_DISABLE_COPY(QJSValuePrivate) - inline bool isJSBased() const; - inline bool isNumberBased() const; - inline bool isStringBased() const; - inline bool prepareArgumentsForCall(v8::Handle<v8::Value> argv[], const QJSValueList& arguments) const; - - friend class QV8Engine; + QJSValuePrivate(QQmlJS::VM::ExecutionEngine *e, const QQmlJS::VM::Value &v) + : PersistentValuePrivate(e, v) + , string(QString()) + {} + QJSValuePrivate(const QQmlJS::VM::Value &v) + : PersistentValuePrivate(v) + , string(QString()) + {} + QJSValuePrivate(const QString &s) + : PersistentValuePrivate() + , string(s) + { + value = QQmlJS::VM::Value::fromString(&string); + } + + QQmlJS::VM::Value getValue(QQmlJS::VM::ExecutionEngine *e) { + if (value.asString() == &string) { + engine = e; + value = QQmlJS::VM::Value::fromString(e->newString(string.toQString())); + } + return value; + } + + static QJSValuePrivate *get(const QJSValue &v) { return v.d; } + + QQmlJS::VM::String string; }; -Q_DECLARE_OPERATORS_FOR_FLAGS(QJSValuePrivate::PropertyFlags) - QT_END_NAMESPACE #endif diff --git a/src/qml/qml/v8/qjsvalueiterator.cpp b/src/qml/qml/v8/qjsvalueiterator.cpp index 67646c9eb4..b3494574bc 100644 --- a/src/qml/qml/v8/qjsvalueiterator.cpp +++ b/src/qml/qml/v8/qjsvalueiterator.cpp @@ -42,11 +42,6 @@ #include "qjsvalueiterator.h" #include "qjsvalueiterator_p.h" -#include "qscriptisolate_p.h" -#include "qjsvalue_p.h" -#include "qv8engine_p.h" -#include "qscript_impl_p.h" - QT_BEGIN_NAMESPACE /*! @@ -84,14 +79,18 @@ QT_BEGIN_NAMESPACE first property). */ QJSValueIterator::QJSValueIterator(const QJSValue& object) - : d_ptr(new QJSValueIteratorPrivate(QJSValuePrivate::get(object))) -{} + : d_ptr(0) +{ + // ### +} /*! Destroys the iterator. */ QJSValueIterator::~QJSValueIterator() -{} +{ + // ### +} /*! Returns true if there is at least one item ahead of the iterator @@ -102,9 +101,7 @@ QJSValueIterator::~QJSValueIterator() */ bool QJSValueIterator::hasNext() const { - Q_D(const QJSValueIterator); - QScriptIsolate api(d->engine()); - return d->hasNext(); + // ### } /*! @@ -120,9 +117,7 @@ bool QJSValueIterator::hasNext() const */ bool QJSValueIterator::next() { - Q_D(QJSValueIterator); - QScriptIsolate api(d->engine()); - return d->next(); + // ### } /*! @@ -133,9 +128,7 @@ bool QJSValueIterator::next() */ QString QJSValueIterator::name() const { - Q_D(const QJSValueIterator); - QScriptIsolate api(d->engine()); - return d_ptr->name(); + // ### } @@ -147,9 +140,7 @@ QString QJSValueIterator::name() const */ QJSValue QJSValueIterator::value() const { - Q_D(const QJSValueIterator); - QScriptIsolate api(d->engine()); - return QJSValuePrivate::get(d->value()); + // ### } @@ -160,10 +151,7 @@ QJSValue QJSValueIterator::value() const */ QJSValueIterator& QJSValueIterator::operator=(QJSValue& object) { - Q_D(QJSValueIterator); - QScriptIsolate api(d->engine()); - d_ptr.reset(new QJSValueIteratorPrivate(QJSValuePrivate::get(object))); - return *this; + // ### } QT_END_NAMESPACE diff --git a/src/qml/qml/v8/qjsvalueiterator.h b/src/qml/qml/v8/qjsvalueiterator.h index b4f90a44b7..e204558e90 100644 --- a/src/qml/qml/v8/qjsvalueiterator.h +++ b/src/qml/qml/v8/qjsvalueiterator.h @@ -42,8 +42,8 @@ #ifndef QSCRIPTVALUEITERATOR_H #define QSCRIPTVALUEITERATOR_H -#include <QtQml/qtqmlglobal.h> #include <QtQml/qjsvalue.h> +#include <QtQml/qtqmlglobal.h> #include <QtCore/qscopedpointer.h> QT_BEGIN_NAMESPACE diff --git a/src/qml/qml/v8/qjsvalueiterator_impl_p.h b/src/qml/qml/v8/qjsvalueiterator_impl_p.h deleted file mode 100644 index f7b6943f57..0000000000 --- a/src/qml/qml/v8/qjsvalueiterator_impl_p.h +++ /dev/null @@ -1,143 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -#ifndef QJSVALUEITERATOR_IMPL_P_H -#define QJSVALUEITERATOR_IMPL_P_H - -#include "qjsvalueiterator_p.h" -#include <private/qv8engine_p.h> -#include "qjsconverter_p.h" - -QT_BEGIN_NAMESPACE - -inline QJSValueIteratorPrivate::QJSValueIteratorPrivate(const QJSValuePrivate* value) - : m_object(const_cast<QJSValuePrivate*>(value)) - , m_index(0) - , m_count(0) -{ - Q_ASSERT(value); - QV8Engine *engine = m_object->engine(); - if (!m_object->isObject()) - m_object = 0; - else { - QScriptIsolate api(engine, QScriptIsolate::NotNullEngine); - v8::HandleScope scope; - - v8::Handle<v8::Value> tmp = *value; - v8::Handle<v8::Object> obj = v8::Handle<v8::Object>::Cast(tmp); - v8::Local<v8::Array> names; - - // FIXME we need newer V8! - //names = obj->GetOwnPropertyNames(); - names = engine->getOwnPropertyNames(obj); - m_names = v8::Persistent<v8::Array>::New(names); - m_count = names->Length(); - - engine->registerValueIterator(this); - } -} - -inline QJSValueIteratorPrivate::~QJSValueIteratorPrivate() -{ - if (isValid()) { - engine()->unregisterValueIterator(this); - m_names.Dispose(); - } -} - -inline void QJSValueIteratorPrivate::invalidate() -{ - m_names.Dispose(); - m_object.reset(); - m_index = 0; - m_count = 0; -} - -inline bool QJSValueIteratorPrivate::hasNext() const -{ - return isValid() ? m_index < m_count : false; -} - -inline bool QJSValueIteratorPrivate::next() -{ - if (hasNext()) { - ++m_index; - return true; - } - return false; -} - -inline QString QJSValueIteratorPrivate::name() const -{ - if (!isValid()) - return QString(); - - v8::HandleScope handleScope; - return QJSConverter::toString(m_names->Get(m_index - 1)->ToString()); -} - -inline QScriptPassPointer<QJSValuePrivate> QJSValueIteratorPrivate::value() const -{ - if (!isValid()) - return new QJSValuePrivate(); - - v8::HandleScope handleScope; - return m_object->property(m_names->Get(m_index - 1)->ToString()); -} - -inline bool QJSValueIteratorPrivate::isValid() const -{ - bool result = m_object ? !m_object->isUndefined() : false; - // We know that if this object is still valid then it is an object - // if this assumption is not correct then some other logic in this class - // have to be changed too. - Q_ASSERT(!result || m_object->isObject()); - return result; -} - -inline QV8Engine* QJSValueIteratorPrivate::engine() const -{ - return m_object ? m_object->engine() : 0; -} - -QT_END_NAMESPACE - -#endif // QJSVALUEITERATOR_IMPL_P_H diff --git a/src/qml/qml/v8/qjsvalueiterator_p.h b/src/qml/qml/v8/qjsvalueiterator_p.h index 2d36ac3ca5..0ab5acd0f4 100644 --- a/src/qml/qml/v8/qjsvalueiterator_p.h +++ b/src/qml/qml/v8/qjsvalueiterator_p.h @@ -42,10 +42,7 @@ #ifndef QJSVALUEITERATOR_P_H #define QJSVALUEITERATOR_P_H -#include <private/qintrusivelist_p.h> -#include "qjsvalue_p.h" - -#include <private/qv8_p.h> +#include "qjsvalue.h" QT_BEGIN_NAMESPACE @@ -54,30 +51,6 @@ class QV8Engine; class QJSValueIteratorPrivate { public: - inline QJSValueIteratorPrivate(const QJSValuePrivate* value); - inline ~QJSValueIteratorPrivate(); - - inline bool hasNext() const; - inline bool next(); - - inline QString name() const; - - inline QScriptPassPointer<QJSValuePrivate> value() const; - - inline bool isValid() const; - inline QV8Engine* engine() const; - - inline void invalidate(); -private: - Q_DISABLE_COPY(QJSValueIteratorPrivate) - - QIntrusiveListNode m_node; - QScriptSharedDataPointer<QJSValuePrivate> m_object; - v8::Persistent<v8::Array> m_names; - uint32_t m_index; - uint32_t m_count; - - friend class QV8Engine; }; diff --git a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp index 309d896d86..d04cc4cee9 100644 --- a/src/qml/qml/v8/qqmlbuiltinfunctions.cpp +++ b/src/qml/qml/v8/qqmlbuiltinfunctions.cpp @@ -47,7 +47,7 @@ #include <private/qqmlstringconverters_p.h> #include <private/qqmllocale_p.h> #include <private/qv8engine_p.h> -#include <private/qjsconverter_impl_p.h> +#include <private/qjsconverter_p.h> #include <private/qv8profilerservice_p.h> #include <private/qqmlprofilerservice_p.h> diff --git a/src/qml/qml/v8/qscript_impl_p.h b/src/qml/qml/v8/qscript_impl_p.h deleted file mode 100644 index 41791189a7..0000000000 --- a/src/qml/qml/v8/qscript_impl_p.h +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -// -// 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. -// - -#ifndef QSCRIPT_IMPL_P_H -#define QSCRIPT_IMPL_P_H - -#include "qv8engine_impl_p.h" -#include "qjsvalue_impl_p.h" -#include "qjsvalueiterator_impl_p.h" -#include "qjsconverter_impl_p.h" - -#endif //QSCRIPT_IMPL_P_H diff --git a/src/qml/qml/v8/qscriptoriginalglobalobject_p.h b/src/qml/qml/v8/qscriptoriginalglobalobject_p.h deleted file mode 100644 index 2ecdbdac91..0000000000 --- a/src/qml/qml/v8/qscriptoriginalglobalobject_p.h +++ /dev/null @@ -1,177 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -#ifndef QSCRIPTORIGINALGLOBALOBJECT_P_H -#define QSCRIPTORIGINALGLOBALOBJECT_P_H - -#include "QtCore/qglobal.h" -#include "qjsvalue_p.h" - -#include <private/qv8_p.h> - -QT_BEGIN_NAMESPACE - -class QV8Engine; - -/*! - \internal - This class is a workaround for missing V8 API functionality. This class keeps all important - properties of an original (default) global object, so we can use it even if the global object was - changed. - - FIXME this class is a container for workarounds :-) it should be replaced by proper API calls. - - The class have to be created on the QV8Engine creation time (before any change got applied to - global object). - - \attention All methods (apart from constructor) assumes that a context and a scope are prepared correctly. -*/ -class QScriptOriginalGlobalObject -{ -public: - inline QScriptOriginalGlobalObject() {} - inline void init(v8::Handle<v8::Context> context); - inline void destroy(); - - inline QJSValuePrivate::PropertyFlags getPropertyFlags(v8::Handle<v8::Object> object, v8::Handle<v8::Value> property); - inline v8::Local<v8::Object> getOwnPropertyDescriptor(v8::Handle<v8::Object> object, v8::Handle<v8::Value> property) const; - inline bool strictlyEquals(v8::Handle<v8::Object> object); -private: - Q_DISABLE_COPY(QScriptOriginalGlobalObject) - - // Copy of constructors and prototypes used in isType functions. - v8::Persistent<v8::Function> m_ownPropertyDescriptor; - v8::Persistent<v8::Object> m_globalObject; -}; - -void QScriptOriginalGlobalObject::init(v8::Handle<v8::Context> context) -{ - // Please notice that engine is not fully initialized at this point. - - v8::Context::Scope contextScope(context); - - v8::HandleScope scope; - - m_globalObject = v8::Persistent<v8::Object>::New(context->Global()); - - v8::Local<v8::Object> objectConstructor = m_globalObject->Get(v8::String::New("Object"))->ToObject(); - Q_ASSERT(objectConstructor->IsObject()); - { // Initialize m_ownPropertyDescriptor. - v8::Local<v8::Value> ownPropertyDescriptor = objectConstructor->Get(v8::String::New("getOwnPropertyDescriptor")); - Q_ASSERT(!ownPropertyDescriptor.IsEmpty()); - m_ownPropertyDescriptor = v8::Persistent<v8::Function>::New(v8::Local<v8::Function>::Cast(ownPropertyDescriptor)); - } -} - -/*! - \internal - QScriptOriginalGlobalObject lives as long as QV8Engine that keeps it. In ~QSEP - the v8 context is removed, so we need to remove our handlers before. to break this dependency - destroy method should be called before or insight QSEP destructor. -*/ -inline void QScriptOriginalGlobalObject::destroy() -{ - m_ownPropertyDescriptor.Dispose(); - m_globalObject.Dispose(); - // After this line this instance is unusable. -} - -inline QJSValuePrivate::PropertyFlags QScriptOriginalGlobalObject::getPropertyFlags(v8::Handle<v8::Object> object, v8::Handle<v8::Value> property) -{ - Q_ASSERT(object->IsObject()); - Q_ASSERT(!property.IsEmpty()); - v8::Local<v8::Object> descriptor = getOwnPropertyDescriptor(object, property); - if (descriptor.IsEmpty()) { -// // Property isn't owned by this object. -// if (!(mode & QScriptValue::ResolvePrototype)) -// return 0; - v8::Local<v8::Value> prototype = object->GetPrototype(); - if (prototype->IsNull()) - return 0; - return getPropertyFlags(v8::Local<v8::Object>::Cast(prototype), property); - } - v8::Local<v8::String> writableName = v8::String::New("writable"); - v8::Local<v8::String> configurableName = v8::String::New("configurable"); - v8::Local<v8::String> enumerableName = v8::String::New("enumerable"); -// v8::Local<v8::String> getName = v8::String::New("get"); -// v8::Local<v8::String> setName = v8::String::New("set"); - - unsigned flags = 0; - - if (!descriptor->Get(configurableName)->BooleanValue()) - flags |= QJSValuePrivate::Undeletable; - if (!descriptor->Get(enumerableName)->BooleanValue()) - flags |= QJSValuePrivate::SkipInEnumeration; - - //"writable" is only a property of the descriptor if it is not an accessor - if (descriptor->Has(writableName)) { - if (!descriptor->Get(writableName)->BooleanValue()) - flags |= QJSValuePrivate::ReadOnly; - } else { -// if (descriptor->Get(getName)->IsObject()) -// flags |= QScriptValue::PropertyGetter; -// if (descriptor->Get(setName)->IsObject()) -// flags |= QScriptValue::PropertySetter; - } - - return QJSValuePrivate::PropertyFlag(flags); -} - -inline v8::Local<v8::Object> QScriptOriginalGlobalObject::getOwnPropertyDescriptor(v8::Handle<v8::Object> object, v8::Handle<v8::Value> property) const -{ - Q_ASSERT(object->IsObject()); - Q_ASSERT(!property.IsEmpty()); - // FIXME do we need try catch here? - v8::Handle<v8::Value> argv[] = {object, property}; - v8::Local<v8::Value> descriptor = m_ownPropertyDescriptor->Call(m_globalObject, /* argc */ 2, argv); - if (descriptor.IsEmpty() || !descriptor->IsObject()) - return v8::Local<v8::Object>(); - return v8::Local<v8::Object>::Cast(descriptor); -} - -inline bool QScriptOriginalGlobalObject::strictlyEquals(v8::Handle<v8::Object> object) -{ - return m_globalObject->GetPrototype()->StrictEquals(object); -} - -QT_END_NAMESPACE - -#endif diff --git a/src/qml/qml/v8/qscriptshareddata_p.h b/src/qml/qml/v8/qscriptshareddata_p.h deleted file mode 100644 index 70289cba46..0000000000 --- a/src/qml/qml/v8/qscriptshareddata_p.h +++ /dev/null @@ -1,169 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -// -// 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. -// - -#ifndef QSCRIPTSHAREDDATA_P_H -#define QSCRIPTSHAREDDATA_P_H - -#include "qglobal.h" -#include "qshareddata.h" - -QT_BEGIN_NAMESPACE - -/*! - \internal - This class should have the same interface as the QSharedData, but implementation doesn't - need to be thread safe, so atomic ref count was replaced by normal integer value. -*/ -class QScriptSharedData -{ -public: - class ReferenceCounter { - // FIXME shouldn't it be uint or something longer? - mutable int m_ref; - ReferenceCounter(int ref) : m_ref(ref) {} - ~ReferenceCounter() { Q_ASSERT_X(!m_ref, Q_FUNC_INFO, "Memory problem found"); } - public: - bool ref() { return ++m_ref; } - bool deref() { return --m_ref; } - friend class QScriptSharedData; - }; - - ReferenceCounter ref; - inline QScriptSharedData() : ref(0) { } - -private: - Q_DISABLE_COPY(QScriptSharedData) -}; - - -template <class T> class QScriptPassPointer; - -// FIXME: that could be reimplemented to not check for a null value. -template<class T> -class QScriptSharedDataPointer : public QExplicitlySharedDataPointer<T> -{ -public: - inline QScriptSharedDataPointer() {} - explicit QScriptSharedDataPointer(QScriptPassPointer<T> data) : QExplicitlySharedDataPointer<T>(data.give()) {} - explicit QScriptSharedDataPointer(T *data) : QExplicitlySharedDataPointer<T>(data) {} - - inline QScriptSharedDataPointer<T> &operator=(const QScriptPassPointer<T> &other) - { - this->QExplicitlySharedDataPointer<T>::operator =(other.give()); - return *this; - } - inline QScriptSharedDataPointer<T> &operator=(T *other) - { - this->QExplicitlySharedDataPointer<T>::operator =(other); - return *this; - } -}; - -// FIXME: that could be reimplemented to not check for a null value. -template <class T> -class QScriptPassPointer { -public: - QScriptPassPointer(T *data) : m_ptr(data) {} - inline QScriptPassPointer() { m_ptr = 0; } - inline QScriptPassPointer(const QScriptPassPointer<T> &other) : m_ptr(other.give()) {} - inline ~QScriptPassPointer() { Q_ASSERT_X(!m_ptr, Q_FUNC_INFO, "Ownership of the QScriptPassPointer hasn't been taken"); } - - inline T &operator*() const { return *m_ptr; } - inline T *operator->() { return m_ptr; } - inline T *operator->() const { return m_ptr; } - inline T *data() const { return m_ptr; } - inline const T *constData() const { return m_ptr; } - - inline bool operator==(const QScriptPassPointer<T> &other) const { return m_ptr == other.m_ptr; } - inline bool operator!=(const QScriptPassPointer<T> &other) const { return m_ptr != other.m_ptr; } - inline bool operator==(const QScriptSharedDataPointer<T> &other) const { return m_ptr == other.m_ptr; } - inline bool operator!=(const QScriptSharedDataPointer<T> &other) const { return m_ptr != other.m_ptr; } - inline bool operator==(const T *ptr) const { return m_ptr == ptr; } - inline bool operator!=(const T *ptr) const { return m_ptr != ptr; } - - inline operator bool () const { return m_ptr != 0; } - inline bool operator!() const { return !m_ptr; } - - inline QScriptPassPointer<T> & operator=(const QScriptPassPointer<T> &other) - { - if (other.m_ptr != m_ptr) { - if (m_ptr) - delete m_ptr; - m_ptr = other.give(); - } - return *this; - } - - inline QScriptPassPointer &operator=(T *other) - { - if (other != m_ptr) { - if (m_ptr) - delete m_ptr; - m_ptr = other; - } - return *this; - } - - inline T* give() const - { - T* result = m_ptr; - m_ptr = 0; - return result; - } - -private: - mutable T* m_ptr; -}; - -QT_END_NAMESPACE - -#endif // QSCRIPTSHAREDDATA_P_H diff --git a/src/qml/qml/v8/qscripttools_p.h b/src/qml/qml/v8/qscripttools_p.h deleted file mode 100644 index 29adfa4ef9..0000000000 --- a/src/qml/qml/v8/qscripttools_p.h +++ /dev/null @@ -1,86 +0,0 @@ -/**************************************************************************** -** -** 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$ -** -****************************************************************************/ - -// -// 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. -// - - -#ifndef QSCRIPTTOOLS_P_H -#define QSCRIPTTOOLS_P_H - -#include <private/qintrusivelist_p.h> - -QT_BEGIN_NAMESPACE - -template<class N, QIntrusiveListNode N::*member> -class QScriptIntrusiveList : public QIntrusiveList<N, member> -{ -public: - inline void insert(N *n); - inline void remove(N *n); -}; - -template<class N, QIntrusiveListNode N::*member> -void QScriptIntrusiveList<N, member>::insert(N *n) -{ - Q_ASSERT_X(!this->contains(n), Q_FUNC_INFO, "Can't insert a value which is in the list already"); - Q_ASSERT_X(!(n->*member).isInList(), Q_FUNC_INFO, "Can't insert a value which is in another list"); - QIntrusiveList<N, member>::insert(n); -} - -template<class N, QIntrusiveListNode N::*member> -void QScriptIntrusiveList<N, member>::remove(N *n) -{ - Q_ASSERT_X(this->contains(n), Q_FUNC_INFO, "Can't remove a value which is not in the list"); - QIntrusiveList<N, member>::remove(n); -} - -QT_END_NAMESPACE - -#endif //QSCRIPTTOOLS_P_H diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp index 5cb9b61e8f..715737bc90 100644 --- a/src/qml/qml/v8/qv8engine.cpp +++ b/src/qml/qml/v8/qv8engine.cpp @@ -55,14 +55,17 @@ #include <private/qqmlglobal_p.h> #include <private/qqmlmemoryprofiler_p.h> #include <private/qqmlplatform_p.h> +#include <private/qjsconverter_p.h> -#include "qscript_impl_p.h" #include "qv8domerrors_p.h" #include "qv8sqlerrors_p.h" #include <QtCore/qjsonarray.h> #include <QtCore/qjsonobject.h> #include <QtCore/qjsonvalue.h> +#include <QtCore/qdatetime.h> + +#include <private/qv8engine_impl_p.h> Q_DECLARE_METATYPE(QList<int>) @@ -144,9 +147,11 @@ QV8Engine::QV8Engine(QJSEngine* qq, ContextOwnership ownership) v8::HandleScope handle_scope; m_context = (ownership == CreateNewContext) ? v8::Context::New() : v8::Persistent<v8::Context>::New(v8::Context::GetCurrent()); qPersistentRegister(m_context); - m_originalGlobalObject.init(m_context); v8::Context::Scope context_scope(m_context); + m_v4Engine = v8::Isolate::GetEngine(); + m_v4Engine->publicEngine = q; + v8::V8::SetUserObjectComparisonCallbackFunction(ObjectComparisonCallback); QV8GCCallback::registerGcPrologueCallback(); m_strongReferencer = qPersistentNew(v8::Object::New()); @@ -184,8 +189,6 @@ QV8Engine::~QV8Engine() qPersistentDispose(m_freezeObject); qPersistentDispose(m_getOwnPropertyNames); - invalidateAllValues(); - qPersistentDispose(m_strongReferencer); m_jsonWrapper.destroy(); @@ -200,8 +203,6 @@ QV8Engine::~QV8Engine() qPersistentDispose(m_bindingFlagKey); - m_originalGlobalObject.destroy(); - if (m_ownsV8Context) qPersistentDispose(m_context); } @@ -411,8 +412,10 @@ v8::Handle<v8::Value> QV8Engine::fromVariant(const QVariant &variant) } else if (type == qMetaTypeId<QJSValue>()) { const QJSValue *value = reinterpret_cast<const QJSValue *>(ptr); QJSValuePrivate *valuep = QJSValuePrivate::get(*value); - if (valuep->assignEngine(this)) - return v8::Local<v8::Value>::New(*valuep); + valuep->engine = m_v4Engine; + return v8::Local<v8::Value>::New(v8::Value::fromVmValue(valuep->getValue(valuep->engine))); +// if (valuep->assignEngine(this)) +// return v8::Local<v8::Value>::New(*valuep); } else if (type == qMetaTypeId<QList<QObject *> >()) { // XXX Can this be made more by using Array as a prototype and implementing // directly against QList<QObject*>? @@ -1073,7 +1076,7 @@ v8::Handle<v8::Value> QV8Engine::metaTypeToJS(int type, const void *data) break; default: if (type == qMetaTypeId<QJSValue>()) { - return QJSValuePrivate::get(*reinterpret_cast<const QJSValue*>(data))->asV8Value(this); + return v8::Value::fromVmValue(QJSValuePrivate::get(*reinterpret_cast<const QJSValue*>(data))->value); } else { QByteArray typeName = QMetaType::typeName(type); if (typeName.endsWith('*') && !*reinterpret_cast<void* const *>(data)) { @@ -1251,7 +1254,7 @@ bool QV8Engine::metaTypeFromJS(v8::Handle<v8::Value> value, int type, void *data *reinterpret_cast<void* *>(data) = 0; return true; } else if (type == qMetaTypeId<QJSValue>()) { - *reinterpret_cast<QJSValue*>(data) = QJSValuePrivate::get(new QJSValuePrivate(this, value)); + *reinterpret_cast<QJSValue*>(data) = QJSValuePrivate::get(new QJSValuePrivate(m_v4Engine, value.get()->vmValue())); return true; } @@ -1385,7 +1388,7 @@ v8::Local<v8::Object> QV8Engine::newVariant(const QVariant &value) return variantWrapper()->newVariant(value); } -QScriptPassPointer<QJSValuePrivate> QV8Engine::evaluate(v8::Handle<v8::Script> script, v8::TryCatch& tryCatch) +QJSValue QV8Engine::evaluate(v8::Handle<v8::Script> script, v8::TryCatch& tryCatch) { v8::HandleScope handleScope; @@ -1393,9 +1396,9 @@ QScriptPassPointer<QJSValuePrivate> QV8Engine::evaluate(v8::Handle<v8::Script> s v8::Handle<v8::Value> exception = tryCatch.Exception(); if (exception.IsEmpty()) { // This is possible on syntax errors like { a:12, b:21 } <- missing "(", ")" around expression. - return new QJSValuePrivate(this); + return QJSValue(); } - return new QJSValuePrivate(this, exception); + return new QJSValuePrivate(m_v4Engine, exception.get()->vmValue()); } v8::Handle<v8::Value> result; result = script->Run(); @@ -1405,21 +1408,21 @@ QScriptPassPointer<QJSValuePrivate> QV8Engine::evaluate(v8::Handle<v8::Script> s //Q_ASSERT(!exception.IsEmpty()); if (exception.IsEmpty()) exception = v8::Exception::Error(v8::String::New("missing exception value")); - return new QJSValuePrivate(this, exception); + return new QJSValuePrivate(m_v4Engine, exception.get()->vmValue()); } - return new QJSValuePrivate(this, result); + return new QJSValuePrivate(m_v4Engine, result.get()->vmValue()); } QJSValue QV8Engine::scriptValueFromInternal(v8::Handle<v8::Value> value) const { if (value.IsEmpty()) - return QJSValuePrivate::get(new QJSValuePrivate(const_cast<QV8Engine*>(this))); - return QJSValuePrivate::get(new QJSValuePrivate(const_cast<QV8Engine*>(this), value)); + return QJSValue(); + return new QJSValuePrivate(m_v4Engine, value.get()->vmValue()); } -QScriptPassPointer<QJSValuePrivate> QV8Engine::newArray(uint length) +QJSValue QV8Engine::newArray(uint length) { - return new QJSValuePrivate(this, v8::Array::New(length)); + return new QJSValuePrivate(m_v4Engine, v8::Array::New(length).get()->vmValue()); } void QV8Engine::startTimer(const QString &timerName) diff --git a/src/qml/qml/v8/qv8engine_impl_p.h b/src/qml/qml/v8/qv8engine_impl_p.h index 8879b67ebb..0eeaced761 100644 --- a/src/qml/qml/v8/qv8engine_impl_p.h +++ b/src/qml/qml/v8/qv8engine_impl_p.h @@ -57,102 +57,92 @@ #include "qjsvalue_p.h" #include "qjsconverter_p.h" #include "qjsvalueiterator_p.h" +#include "qv4errorobject_p.h" QT_BEGIN_NAMESPACE -inline v8::Handle<v8::Value> QV8Engine::makeJSValue(bool value) +v8::Handle<v8::Value> QV8Engine::makeJSValue(bool value) { return value ? v8::True() : v8::False(); } -inline v8::Local<v8::Value> QV8Engine::makeJSValue(int value) +v8::Local<v8::Value> QV8Engine::makeJSValue(int value) { return v8::Integer::New(value); } -inline v8::Local<v8::Value> QV8Engine::makeJSValue(uint value) +v8::Local<v8::Value> QV8Engine::makeJSValue(uint value) { return v8::Integer::NewFromUnsigned(value); } -inline v8::Local<v8::Value> QV8Engine::makeJSValue(double value) +v8::Local<v8::Value> QV8Engine::makeJSValue(double value) { return v8::Number::New(value); } -inline v8::Handle<v8::Value> QV8Engine::makeJSValue(QJSValue::SpecialValue value) { +v8::Handle<v8::Value> QV8Engine::makeJSValue(QJSValue::SpecialValue value) { if (value == QJSValue::NullValue) return v8::Null(); return v8::Undefined(); } -inline v8::Local<v8::Value> QV8Engine::makeJSValue(const QString &value) +v8::Local<v8::Value> QV8Engine::makeJSValue(const QString &value) { return QJSConverter::toString(value); } -class QtScriptBagCleaner -{ -public: - template<class T> - void operator () (T* value) const - { - value->reinitialize(); - } - void operator () (QJSValueIteratorPrivate *iterator) const - { - iterator->invalidate(); - } -}; - -inline void QV8Engine::registerValue(QJSValuePrivate *data) -{ - m_values.insert(data); -} - -inline void QV8Engine::unregisterValue(QJSValuePrivate *data) -{ - m_values.remove(data); -} - -inline void QV8Engine::invalidateAllValues() -{ - ValueList::iterator it; - for (it = m_values.begin(); it != m_values.end(); it = it.erase()) - (*it)->invalidate(); - Q_ASSERT(m_values.isEmpty()); -} - -inline void QV8Engine::registerValueIterator(QJSValueIteratorPrivate *data) -{ - m_valueIterators.insert(data); -} - -inline void QV8Engine::unregisterValueIterator(QJSValueIteratorPrivate *data) -{ - m_valueIterators.remove(data); -} - -inline void QV8Engine::invalidateAllIterators() -{ - ValueIteratorList::iterator it; - for (it = m_valueIterators.begin(); it != m_valueIterators.end(); it = it.erase()) - (*it)->invalidate(); - Q_ASSERT(m_valueIterators.isEmpty()); -} - -/*! - \internal - \note property can be index (v8::Integer) or a property (v8::String) name, according to ECMA script - property would be converted to a string. -*/ -inline QJSValuePrivate::PropertyFlags QV8Engine::getPropertyFlags(v8::Handle<v8::Object> object, v8::Handle<v8::Value> property) -{ - QJSValuePrivate::PropertyFlags flags = m_originalGlobalObject.getPropertyFlags(object, property); - return flags; -} - -QScriptPassPointer<QJSValuePrivate> QV8Engine::evaluate(const QString& program, const QString& fileName, quint16 lineNumber) +//class QtScriptBagCleaner +//{ +//public: +// template<class T> +// void operator () (T* value) const +// { +// value->reinitialize(); +// } +// void operator () (QJSValueIteratorPrivate *iterator) const +// { +// iterator->invalidate(); +// } +//}; + +//void QV8Engine::registerValue(QJSValuePrivate *data) +//{ +// m_values.insert(data); +//} + +//void QV8Engine::unregisterValue(QJSValuePrivate *data) +//{ +// m_values.remove(data); +//} + +//void QV8Engine::invalidateAllValues() +//{ +// ValueList::iterator it; +// for (it = m_values.begin(); it != m_values.end(); it = it.erase()) +// (*it)->invalidate(); +// Q_ASSERT(m_values.isEmpty()); +//} + +//void QV8Engine::registerValueIterator(QJSValueIteratorPrivate *data) +//{ +// m_valueIterators.insert(data); +//} + +//void QV8Engine::unregisterValueIterator(QJSValueIteratorPrivate *data) +//{ +// m_valueIterators.remove(data); +//} + +//void QV8Engine::invalidateAllIterators() +//{ +// ValueIteratorList::iterator it; +// for (it = m_valueIterators.begin(); it != m_valueIterators.end(); it = it.erase()) +// (*it)->invalidate(); +// Q_ASSERT(m_valueIterators.isEmpty()); +//} + +QJSValue QV8Engine::evaluate(const QString& program, const QString& fileName, quint16 lineNumber) { v8::TryCatch tryCatch; v8::ScriptOrigin scriptOrigin(QJSConverter::toString(fileName), v8::Integer::New(lineNumber - 1)); @@ -161,8 +151,8 @@ QScriptPassPointer<QJSValuePrivate> QV8Engine::evaluate(const QString& program, if (script.IsEmpty()) { // TODO: Why don't we get the exception, as with Script::Compile()? // Q_ASSERT(tryCatch.HasCaught()); - v8::Handle<v8::Value> error = v8::Exception::SyntaxError(v8::String::New("")); - return new QJSValuePrivate(this, error); + QQmlJS::VM::Object *error = m_v4Engine->newSyntaxErrorObject(m_v4Engine->current, 0); + return new QJSValuePrivate(m_v4Engine, QQmlJS::VM::Value::fromObject(error)); } return evaluate(script, tryCatch); } diff --git a/src/qml/qml/v8/qv8engine_p.h b/src/qml/qml/v8/qv8engine_p.h index d7941487e3..bf96544670 100644 --- a/src/qml/qml/v8/qv8engine_p.h +++ b/src/qml/qml/v8/qv8engine_p.h @@ -65,10 +65,8 @@ #include <private/qv8_p.h> #include <qjsengine.h> #include <qjsvalue.h> -#include "qjsvalue_p.h" #include "qjsvalueiterator_p.h" -#include "qscriptoriginalglobalobject_p.h" -#include "qscripttools_p.h" +#include "private/qintrusivelist_p.h" #include <private/qqmlpropertycache_p.h> @@ -95,6 +93,11 @@ inline uint qHash(const v8::Handle<v8::Object> &object, uint seed = 0) QT_BEGIN_NAMESPACE +namespace QQmlJS { +namespace VM { + class ExecutionEngine; +} +} // Uncomment the following line to enable global handle debugging. When enabled, all the persistent // handles allocated using qPersistentNew() (or registered with qPersistentRegsiter()) and disposed @@ -247,10 +250,13 @@ public: class Q_QML_PRIVATE_EXPORT QV8Engine { + friend class QJSEngine; typedef QSet<v8::Handle<v8::Object> > V8ObjectSet; public: static QV8Engine* get(QJSEngine* q) { Q_ASSERT(q); return q->handle(); } static QJSEngine* get(QV8Engine* d) { Q_ASSERT(d); return d->q; } + static QQmlJS::VM::ExecutionEngine *getV4(QJSEngine *q) { return q->handle()->m_v4Engine; } + static QQmlJS::VM::ExecutionEngine *getV4(QV8Engine *d) { return d->m_v4Engine; } enum ContextOwnership { AdoptCurrentContext, @@ -272,13 +278,13 @@ public: v8::Local<v8::Object> global() { return m_context->Global(); } v8::Handle<v8::Context> context() const { return m_context; } - inline void registerValue(QJSValuePrivate *data); - inline void unregisterValue(QJSValuePrivate *data); - inline void invalidateAllValues(); +// inline void registerValue(QJSValuePrivate *data); +// inline void unregisterValue(QJSValuePrivate *data); +// inline void invalidateAllValues(); - inline void registerValueIterator(QJSValueIteratorPrivate *data); - inline void unregisterValueIterator(QJSValueIteratorPrivate *data); - inline void invalidateAllIterators(); +// inline void registerValueIterator(QJSValueIteratorPrivate *data); +// inline void unregisterValueIterator(QJSValueIteratorPrivate *data); +// inline void invalidateAllIterators(); QV8ContextWrapper *contextWrapper() { return &m_contextWrapper; } QV8QObjectWrapper *qobjectWrapper() { return &m_qobjectWrapper; } @@ -296,7 +302,6 @@ public: QQmlContextData *callingContext(); v8::Local<v8::Array> getOwnPropertyNames(v8::Handle<v8::Object>); - inline QJSValuePrivate::PropertyFlags getPropertyFlags(v8::Handle<v8::Object> object, v8::Handle<v8::Value> property); void freezeObject(v8::Handle<v8::Value>); inline QString toString(v8::Handle<v8::Value> string); @@ -370,17 +375,17 @@ public: inline Deletable *extensionData(int) const; void setExtensionData(int, Deletable *); - inline v8::Handle<v8::Value> makeJSValue(bool value); - inline v8::Local<v8::Value> makeJSValue(int value); - inline v8::Local<v8::Value> makeJSValue(uint value); - inline v8::Local<v8::Value> makeJSValue(double value); - inline v8::Handle<v8::Value> makeJSValue(QJSValue::SpecialValue value); - inline v8::Local<v8::Value> makeJSValue(const QString &value); + v8::Handle<v8::Value> makeJSValue(bool value); + v8::Local<v8::Value> makeJSValue(int value); + v8::Local<v8::Value> makeJSValue(uint value); + v8::Local<v8::Value> makeJSValue(double value); + v8::Handle<v8::Value> makeJSValue(QJSValue::SpecialValue value); + v8::Local<v8::Value> makeJSValue(const QString &value); - inline QScriptPassPointer<QJSValuePrivate> evaluate(const QString &program, const QString &fileName = QString(), quint16 lineNumber = 1); - QScriptPassPointer<QJSValuePrivate> evaluate(v8::Handle<v8::Script> script, v8::TryCatch& tryCatch); + QJSValue evaluate(const QString &program, const QString &fileName = QString(), quint16 lineNumber = 1); + QJSValue evaluate(v8::Handle<v8::Script> script, v8::TryCatch& tryCatch); - QScriptPassPointer<QJSValuePrivate> newArray(uint length); + QJSValue newArray(uint length); v8::Local<v8::Object> newVariant(const QVariant &variant); v8::Local<v8::Array> variantListToJS(const QVariantList &lst); @@ -450,9 +455,11 @@ public: protected: QJSEngine* q; QQmlEngine *m_engine; + + QQmlJS::VM::ExecutionEngine *m_v4Engine; + bool m_ownsV8Context; v8::Persistent<v8::Context> m_context; - QScriptOriginalGlobalObject m_originalGlobalObject; v8::Persistent<v8::String> m_bindingFlagKey; @@ -497,10 +504,10 @@ private: static v8::Persistent<v8::Object> *findOwnerAndStrength(QObject *object, bool *shouldBeStrong); - typedef QScriptIntrusiveList<QJSValuePrivate, &QJSValuePrivate::m_node> ValueList; - ValueList m_values; - typedef QScriptIntrusiveList<QJSValueIteratorPrivate, &QJSValueIteratorPrivate::m_node> ValueIteratorList; - ValueIteratorList m_valueIterators; +// typedef QIntrusiveList<QJSValuePrivate, &QJSValuePrivate::m_node> ValueList; +// ValueList m_values; +// typedef QIntrusiveList<QJSValueIteratorPrivate, &QJSValueIteratorPrivate::m_node> ValueIteratorList; +// ValueIteratorList m_valueIterators; Q_DISABLE_COPY(QV8Engine) }; diff --git a/src/qml/qml/v8/qv8jsonwrapper.cpp b/src/qml/qml/v8/qv8jsonwrapper.cpp index 4d89551894..8f4e6f429b 100644 --- a/src/qml/qml/v8/qv8jsonwrapper.cpp +++ b/src/qml/qml/v8/qv8jsonwrapper.cpp @@ -41,7 +41,7 @@ #include "qv8jsonwrapper_p.h" #include "qv8engine_p.h" -#include "qjsconverter_impl_p.h" +#include "qjsconverter_p.h" QT_BEGIN_NAMESPACE diff --git a/src/qml/qml/v8/qv8qobjectwrapper.cpp b/src/qml/qml/v8/qv8qobjectwrapper.cpp index 92e00f05da..b59d4806a8 100644 --- a/src/qml/qml/v8/qv8qobjectwrapper.cpp +++ b/src/qml/qml/v8/qv8qobjectwrapper.cpp @@ -49,7 +49,6 @@ #include <private/qqmlvmemetaobject_p.h> #include <private/qqmlbinding_p.h> #include <private/qjsvalue_p.h> -#include <private/qscript_impl_p.h> #include <private/qqmlaccessors_p.h> #include <private/qqmlexpression_p.h> #include <private/qqmlglobal_p.h> @@ -434,7 +433,7 @@ static v8::Handle<v8::Value> LoadProperty(QV8Engine *engine, QObject *object, } else if (property.propType == qMetaTypeId<QJSValue>()) { QJSValue v; ReadFunction(object, property, &v, notifier); - return QJSValuePrivate::get(v)->asV8Value(engine); + return v8::Value::fromVmValue(QJSValuePrivate::get(v)->getValue(QV8Engine::getV4(engine))); } else if (property.isQVariant()) { QVariant v; ReadFunction(object, property, &v, notifier); @@ -2144,7 +2143,7 @@ void CallArgument::fromValue(int callType, QV8Engine *engine, v8::Handle<v8::Val if (type != 0) { cleanup(); type = 0; } if (callType == qMetaTypeId<QJSValue>()) { - qjsValuePtr = new (&allocData) QJSValue(QJSValuePrivate::get(new QJSValuePrivate(engine, value))); + qjsValuePtr = new (&allocData) QJSValue(new QJSValuePrivate(QV8Engine::getV4(engine), value.get()->vmValue())); type = qMetaTypeId<QJSValue>(); } else if (callType == QMetaType::Int) { intValue = quint32(value->Int32Value()); @@ -2233,7 +2232,7 @@ void CallArgument::fromValue(int callType, QV8Engine *engine, v8::Handle<v8::Val v8::Handle<v8::Value> CallArgument::toValue(QV8Engine *engine) { if (type == qMetaTypeId<QJSValue>()) { - return QJSValuePrivate::get(*qjsValuePtr)->asV8Value(engine); + return v8::Value::fromVmValue(QJSValuePrivate::get(*qjsValuePtr)->getValue(QV8Engine::getV4(engine))); } else if (type == QMetaType::Int) { return v8::Integer::New(int(intValue)); } else if (type == QMetaType::UInt) { diff --git a/src/qml/qml/v8/qv8stringwrapper.cpp b/src/qml/qml/v8/qv8stringwrapper.cpp index f069c57b52..7a4a5fcdb2 100644 --- a/src/qml/qml/v8/qv8stringwrapper.cpp +++ b/src/qml/qml/v8/qv8stringwrapper.cpp @@ -41,7 +41,7 @@ #include "qv8stringwrapper_p.h" #include "qjsconverter_p.h" -#include "qjsconverter_impl_p.h" +#include "qjsconverter_p.h" QT_BEGIN_NAMESPACE diff --git a/src/qml/qml/v8/qv8typewrapper.cpp b/src/qml/qml/v8/qv8typewrapper.cpp index e45ebacb90..e7e1f43ebe 100644 --- a/src/qml/qml/v8/qv8typewrapper.cpp +++ b/src/qml/qml/v8/qv8typewrapper.cpp @@ -46,7 +46,6 @@ #include <private/qqmlcontext_p.h> #include <private/qjsvalue_p.h> -#include <private/qscript_impl_p.h> QT_BEGIN_NAMESPACE @@ -196,10 +195,12 @@ v8::Handle<v8::Value> QV8TypeWrapper::Getter(v8::Local<v8::String> property, v8::Handle<v8::Value> rv = v8engine->qobjectWrapper()->getProperty(qobjectSingleton, propertystring, context, QV8QObjectWrapper::IgnoreRevision); return rv; } else if (!siinfo->scriptApi(e).isUndefined()) { + QQmlJS::VM::ExecutionEngine *engine = v8::Isolate::GetEngine(); // NOTE: if used in a binding, changes will not trigger re-evaluation since non-NOTIFYable. - QJSValuePrivate *apiprivate = QJSValuePrivate::get(siinfo->scriptApi(e)); - QScopedPointer<QJSValuePrivate> propertyValue(apiprivate->property(property).give()); - return propertyValue->asV8Value(v8engine); + QQmlJS::VM::Object *o = QJSValuePrivate::get(siinfo->scriptApi(e))->getValue(engine).asObject(); + if (!o) + return v8::Handle<v8::Value>(); + return v8::Value::fromVmValue(o->get(engine->current, property.get()->vmValue().toString(engine->current))); } // Fall through to return empty handle @@ -289,14 +290,14 @@ v8::Handle<v8::Value> QV8TypeWrapper::Setter(v8::Local<v8::String> property, v8engine->qobjectWrapper()->setProperty(qobjectSingleton, propertystring, context, value, QV8QObjectWrapper::IgnoreRevision); } else if (!siinfo->scriptApi(e).isUndefined()) { - QScopedPointer<QJSValuePrivate> setvalp(new QJSValuePrivate(v8engine, value)); - QJSValuePrivate *apiprivate = QJSValuePrivate::get(siinfo->scriptApi(e)); - if (apiprivate->propertyFlags(property) & QJSValuePrivate::ReadOnly) { + QQmlJS::VM::Value setVal = value.get()->vmValue(); + QQmlJS::VM::Object *apiprivate = QJSValuePrivate::get(siinfo->scriptApi(e))->value.asObject(); + if (!apiprivate) { QString error = QLatin1String("Cannot assign to read-only property \"") + v8engine->toString(property) + QLatin1Char('\"'); v8::ThrowException(v8::Exception::Error(v8engine->toString(error))); } else { - apiprivate->setProperty(property, setvalp.data()); + apiprivate->put(v8::Isolate::GetEngine()->current, property.get()->vmValue().stringValue(), setVal); } } } diff --git a/src/qml/qml/v8/script.pri b/src/qml/qml/v8/script.pri index 3439413f5e..09fa426415 100644 --- a/src/qml/qml/v8/script.pri +++ b/src/qml/qml/v8/script.pri @@ -13,9 +13,5 @@ HEADERS += \ $$PWD/qjsconverter_p.h \ $$PWD/qjsconverter_impl_p.h \ $$PWD/qscriptisolate_p.h \ - $$PWD/qscriptshareddata_p.h \ - $$PWD/qscripttools_p.h \ - $$PWD/qscript_impl_p.h \ - $$PWD/qscriptoriginalglobalobject_p.h \ $$PWD/qjsvalueiterator_p.h \ $$PWD/qjsvalueiterator_impl_p.h diff --git a/src/qml/types/qqmllistmodel.cpp b/src/qml/types/qqmllistmodel.cpp index 9609e91b1c..725e5b2544 100644 --- a/src/qml/types/qqmllistmodel.cpp +++ b/src/qml/types/qqmllistmodel.cpp @@ -55,6 +55,7 @@ #include <QtCore/qdebug.h> #include <QtCore/qstack.h> #include <QXmlStreamReader> +#include <QtCore/qdatetime.h> QT_BEGIN_NAMESPACE diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp index 9d9ddd6ef0..4650488705 100644 --- a/src/quick/items/context2d/qquickcanvasitem.cpp +++ b/src/quick/items/context2d/qquickcanvasitem.cpp @@ -50,6 +50,7 @@ #include <qqmlinfo.h> #include <private/qqmlengine_p.h> #include <QtCore/QBuffer> +#include <QtCore/qdatetime.h> QT_BEGIN_NAMESPACE diff --git a/src/quick/items/qquickborderimage.cpp b/src/quick/items/qquickborderimage.cpp index 19d511126d..009a35f25c 100644 --- a/src/quick/items/qquickborderimage.cpp +++ b/src/quick/items/qquickborderimage.cpp @@ -47,6 +47,7 @@ #include <QtQml/qqmlengine.h> #include <QtNetwork/qnetworkreply.h> #include <QtCore/qfile.h> +#include <QtCore/qmath.h> #include <private/qqmlglobal_p.h> diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index dd7357822a..ff56bcaa0e 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -53,6 +53,7 @@ #include <QtGui/qguiapplication.h> #include <QtGui/private/qguiapplication_p.h> #include <QtGui/qstylehints.h> +#include <QtCore/qmath.h> #include "qplatformdefs.h" QT_BEGIN_NAMESPACE diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp index 52f991b475..8da66d5b45 100644 --- a/src/quick/items/qquicktextinput.cpp +++ b/src/quick/items/qquicktextinput.cpp @@ -56,6 +56,7 @@ #include <QtGui/qstylehints.h> #include <QtGui/qinputmethod.h> +#include <QtCore/qmath.h> #ifndef QT_NO_ACCESSIBILITY #include "qaccessible.h" diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index b457c33bed..b01d816661 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -44,6 +44,7 @@ #include <QtCore/QWaitCondition> #include <QtCore/QAnimationDriver> #include <QtCore/QQueue> +#include <QtCore/QTime> #include <QtGui/QGuiApplication> #include <QtGui/QScreen> |