aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/debugger/qv8debugservice.cpp2
-rw-r--r--src/qml/debugger/qv8profilerservice.cpp2
-rw-r--r--src/qml/qml/qqmllocale.cpp2
-rw-r--r--src/qml/qml/v4/qv4bindings.cpp7
-rw-r--r--src/qml/qml/v4vm/qv4dateobject.cpp10
-rw-r--r--src/qml/qml/v4vm/qv4dateobject_p.h5
-rw-r--r--src/qml/qml/v4vm/qv4engine_p.h4
-rw-r--r--src/qml/qml/v4vm/qv4jsir_p.h4
-rw-r--r--src/qml/qml/v4vm/qv4math_p.h2
-rw-r--r--src/qml/qml/v4vm/qv4runtime.cpp5
-rw-r--r--src/qml/qml/v4vm/qv4runtime_p.h4
-rw-r--r--src/qml/qml/v4vm/qv4string.cpp2
-rw-r--r--src/qml/qml/v4vm/qv4v8.cpp5
-rw-r--r--src/qml/qml/v4vm/qv4v8_p.h2
-rw-r--r--src/qml/qml/v4vm/qv4value.cpp25
-rw-r--r--src/qml/qml/v4vm/qv4value_p.h11
-rw-r--r--src/qml/qml/v8/qjsconverter_impl_p.h17
-rw-r--r--src/qml/qml/v8/qjsconverter_p.h22
-rw-r--r--src/qml/qml/v8/qjsengine.cpp39
-rw-r--r--src/qml/qml/v8/qjsvalue.cpp327
-rw-r--r--src/qml/qml/v8/qjsvalue.h17
-rw-r--r--src/qml/qml/v8/qjsvalue_impl_p.h950
-rw-r--r--src/qml/qml/v8/qjsvalue_p.h175
-rw-r--r--src/qml/qml/v8/qjsvalueiterator.cpp36
-rw-r--r--src/qml/qml/v8/qjsvalueiterator.h2
-rw-r--r--src/qml/qml/v8/qjsvalueiterator_impl_p.h143
-rw-r--r--src/qml/qml/v8/qjsvalueiterator_p.h29
-rw-r--r--src/qml/qml/v8/qqmlbuiltinfunctions.cpp2
-rw-r--r--src/qml/qml/v8/qscript_impl_p.h61
-rw-r--r--src/qml/qml/v8/qscriptoriginalglobalobject_p.h177
-rw-r--r--src/qml/qml/v8/qscriptshareddata_p.h169
-rw-r--r--src/qml/qml/v8/qscripttools_p.h86
-rw-r--r--src/qml/qml/v8/qv8engine.cpp41
-rw-r--r--src/qml/qml/v8/qv8engine_impl_p.h130
-rw-r--r--src/qml/qml/v8/qv8engine_p.h55
-rw-r--r--src/qml/qml/v8/qv8jsonwrapper.cpp2
-rw-r--r--src/qml/qml/v8/qv8qobjectwrapper.cpp7
-rw-r--r--src/qml/qml/v8/qv8stringwrapper.cpp2
-rw-r--r--src/qml/qml/v8/qv8typewrapper.cpp17
-rw-r--r--src/qml/qml/v8/script.pri4
-rw-r--r--src/qml/types/qqmllistmodel.cpp1
-rw-r--r--src/quick/items/context2d/qquickcanvasitem.cpp1
-rw-r--r--src/quick/items/qquickborderimage.cpp1
-rw-r--r--src/quick/items/qquickflickable.cpp1
-rw-r--r--src/quick/items/qquicktextinput.cpp1
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop.cpp1
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>