diff options
author | Matthew Vogt <matthew.vogt@nokia.com> | 2012-02-16 14:43:03 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-02-24 04:51:31 +0100 |
commit | b855240b782395f94315f43ea3e7e182299fac48 (patch) | |
tree | bc594c04449be8cd14cd0ab0bb72dafc2be0ffb2 /src/declarative/qml/v8 | |
parent | 6a42a6e0a9a1abdda0d07a5a20b4ac7e45348684 (diff) |
Rename QDeclarative symbols to QQuick and QQml
Symbols beginning with QDeclarative are already exported
by the quick1 module.
Users can apply the bin/rename-qtdeclarative-symbols.sh
script to modify client code using the previous names of the
renamed symbols.
Task-number: QTBUG-23737
Change-Id: Ifaa482663767634931e8711a8e9bf6e404859e66
Reviewed-by: Martin Jones <martin.jones@nokia.com>
Diffstat (limited to 'src/declarative/qml/v8')
57 files changed, 0 insertions, 15215 deletions
diff --git a/src/declarative/qml/v8/notes.txt b/src/declarative/qml/v8/notes.txt deleted file mode 100644 index ff5a289b7c..0000000000 --- a/src/declarative/qml/v8/notes.txt +++ /dev/null @@ -1,4 +0,0 @@ -Removed backwards compatible imports - QTBUG-17518 - -autotest print() taking objects that don't ToString() -autotest QDeclarativeV8Function diff --git a/src/declarative/qml/v8/qdeclarativebuiltinfunctions.cpp b/src/declarative/qml/v8/qdeclarativebuiltinfunctions.cpp deleted file mode 100644 index 12f06e6b76..0000000000 --- a/src/declarative/qml/v8/qdeclarativebuiltinfunctions.cpp +++ /dev/null @@ -1,1320 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qdeclarativebuiltinfunctions_p.h" - -#include <QtDeclarative/qdeclarativecomponent.h> -#include <private/qdeclarativeengine_p.h> -#include <private/qdeclarativecomponent_p.h> -#include <private/qdeclarativestringconverters_p.h> -#include <private/qdeclarativelocale_p.h> -#include <private/qv8engine_p.h> -#include <private/qjsconverter_impl_p.h> - -#include <private/qv8profilerservice_p.h> -#include <private/qdeclarativeprofilerservice_p.h> - -#include <QtCore/qstring.h> -#include <QtCore/qdatetime.h> -#include <QtCore/qcryptographichash.h> -#include <QtCore/qrect.h> -#include <QtCore/qsize.h> -#include <QtCore/qpoint.h> -#include <QtCore/qurl.h> -#include <QtCore/qfile.h> -#include <QtCore/qcoreapplication.h> - -#include <QtGui/qcolor.h> -#include <QtGui/qvector3d.h> -#include <QtGui/qvector4d.h> -#include <QtGui/qdesktopservices.h> -#include <QtGui/qfontdatabase.h> - -QT_BEGIN_NAMESPACE - -namespace QDeclarativeBuiltinFunctions { - -enum ConsoleLogTypes { - Log, - Warn, - Error -}; - -static void jsContext(v8::Handle<v8::Value> *file, int *line, v8::Handle<v8::Value> *function) { - v8::Local<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace(1); - if (stackTrace->GetFrameCount()) { - v8::Local<v8::StackFrame> frame = stackTrace->GetFrame(0); - *file = frame->GetScriptName(); - *line = frame->GetLineNumber(); - *function = frame->GetFunctionName(); - } -} - -static QString jsStack() { - QStringList stackFrames; - - //The v8 default is currently 10 stack frames. - v8::Handle<v8::StackTrace> stackTrace = - v8::StackTrace::CurrentStackTrace(10, v8::StackTrace::kOverview); - int stackCount = stackTrace->GetFrameCount(); - - for (int i = 0; i < stackCount; i++) { - v8::Local<v8::StackFrame> frame = stackTrace->GetFrame(i); - v8::Handle<v8::String> function(frame->GetFunctionName()); - v8::Handle<v8::String> script(frame->GetScriptName()); - int lineNumber = frame->GetLineNumber(); - int columnNumber = frame->GetColumn(); - - QString stackFrame = - QString::fromLatin1("%1 (%2:%3:%4)").arg(QJSConverter::toString(function), - QJSConverter::toString(script), - QString::number(lineNumber), - QString::number(columnNumber)); - stackFrames.append(stackFrame); - } - return stackFrames.join(QLatin1String("\n")); -} - -v8::Handle<v8::Value> console(ConsoleLogTypes logType, const v8::Arguments &args, - bool printStack = false) -{ - v8::HandleScope handleScope; - - QString result; - for (int i = 0; i < args.Length(); ++i) { - if (i != 0) - result.append(QLatin1Char(' ')); - - v8::Local<v8::Value> value = args[i]; - //Check for Object Type - if (value->IsObject() && !value->IsFunction() - && !value->IsArray() && !value->IsDate() - && !value->IsRegExp()) { - result.append(QLatin1String("Object")); - } else { - v8::Local<v8::String> jsstr = value->ToString(); - QString tmp = V8ENGINE()->toString(jsstr); - if (value->IsArray()) - result.append(QString::fromLatin1("[%1]").arg(tmp)); - else - result.append(tmp); - } - } - - if (printStack) { - result.append(QLatin1String("\n")); - result.append(jsStack()); - } - - v8::Handle<v8::Value> fileHandle; - v8::Handle<v8::Value> functionHandle; - int line; - - jsContext(&fileHandle, &line, &functionHandle); - - switch (logType) { - case Log: - QMessageLogger(*v8::String::AsciiValue(fileHandle), line, - *v8::String::AsciiValue(functionHandle)).debug("%s", qPrintable(result)); - break; - case Warn: - QMessageLogger(*v8::String::AsciiValue(fileHandle), line, - *v8::String::AsciiValue(functionHandle)).warning("%s", qPrintable(result)); - break; - case Error: - QMessageLogger(*v8::String::AsciiValue(fileHandle), line, - *v8::String::AsciiValue(functionHandle)).critical("%s", qPrintable(result)); - break; - default: - break; - } - - return v8::Undefined(); -} - -v8::Handle<v8::Value> gc(const v8::Arguments &args) -{ - Q_UNUSED(args); - QV8Engine::gc(); - return v8::Undefined(); -} - -v8::Handle<v8::Value> consoleError(const v8::Arguments &args) -{ - return console(Error, args); -} - -v8::Handle<v8::Value> consoleLog(const v8::Arguments &args) -{ - //console.log - //console.debug - //console.info - //print - return console(Log, args); -} - -v8::Handle<v8::Value> consoleProfile(const v8::Arguments &args) -{ - //DeclarativeDebugTrace cannot handle nested profiling - //although v8 can handle several profiling at once, - //we do not allow that. Hence, we pass an empty(default) title - Q_UNUSED(args); - QString title; - - - - v8::Handle<v8::Value> file; - v8::Handle<v8::Value> function; - int line; - jsContext(&file, &line, &function); - - if (QDeclarativeProfilerService::startProfiling()) { - QV8ProfilerService::instance()->startProfiling(title); - - QMessageLogger(*v8::String::AsciiValue(file), line, - *v8::String::AsciiValue(function)).debug("Profiling started."); - } else { - QMessageLogger(*v8::String::AsciiValue(file), line, - *v8::String::AsciiValue(function)).warning( - "Profiling is already in progress. First, end current profiling session."); - } - - return v8::Undefined(); -} - -v8::Handle<v8::Value> consoleProfileEnd(const v8::Arguments &args) -{ - //DeclarativeDebugTrace cannot handle nested profiling - //although v8 can handle several profiling at once, - //we do not allow that. Hence, we pass an empty(default) title - Q_UNUSED(args); - QString title; - - v8::Handle<v8::Value> file; - v8::Handle<v8::Value> function; - int line; - jsContext(&file, &line, &function); - - if (QDeclarativeProfilerService::stopProfiling()) { - QV8ProfilerService *profiler = QV8ProfilerService::instance(); - profiler->stopProfiling(title); - QDeclarativeProfilerService::sendProfilingData(); - profiler->sendProfilingData(); - - QMessageLogger(*v8::String::AsciiValue(file), line, - *v8::String::AsciiValue(function)).debug("Profiling ended."); - } else { - QMessageLogger(*v8::String::AsciiValue(file), line, - *v8::String::AsciiValue(function)).warning("Profiling was not started."); - } - - return v8::Undefined(); -} - -v8::Handle<v8::Value> consoleTime(const v8::Arguments &args) -{ - if (args.Length() != 1) - V8THROW_ERROR("console.time(): Invalid arguments"); - QString name = V8ENGINE()->toString(args[0]); - V8ENGINE()->startTimer(name); - return v8::Undefined(); -} - -v8::Handle<v8::Value> consoleTimeEnd(const v8::Arguments &args) -{ - if (args.Length() != 1) - V8THROW_ERROR("console.time(): Invalid arguments"); - QString name = V8ENGINE()->toString(args[0]); - bool wasRunning; - qint64 elapsed = V8ENGINE()->stopTimer(name, &wasRunning); - if (wasRunning) { - qDebug("%s: %llims", qPrintable(name), elapsed); - } - return v8::Undefined(); -} - -v8::Handle<v8::Value> consoleCount(const v8::Arguments &args) -{ - // first argument: name to print. Ignore any additional arguments - QString name; - if (args.Length() > 0) - name = V8ENGINE()->toString(args[0]); - - v8::Handle<v8::StackTrace> stackTrace = - v8::StackTrace::CurrentStackTrace(1, v8::StackTrace::kOverview); - - if (stackTrace->GetFrameCount()) { - v8::Local<v8::StackFrame> frame = stackTrace->GetFrame(0); - - QString scriptName = V8ENGINE()->toString(frame->GetScriptName()); - QString functionName = V8ENGINE()->toString(frame->GetFunctionName()); - int line = frame->GetLineNumber(); - int column = frame->GetColumn(); - - int value = V8ENGINE()->consoleCountHelper(scriptName, line, column); - QString message = name + QLatin1String(": ") + QString::number(value); - - QMessageLogger(qPrintable(scriptName), line, - qPrintable(functionName)).debug("%s", qPrintable(message)); - } - - return v8::Undefined(); -} - -v8::Handle<v8::Value> consoleTrace(const v8::Arguments &args) -{ - if (args.Length() != 0) - V8THROW_ERROR("console.trace(): Invalid arguments"); - - QString stack = jsStack(); - - v8::Handle<v8::Value> file; - v8::Handle<v8::Value> function; - int line; - jsContext(&file, &line, &function); - - QMessageLogger(*v8::String::AsciiValue(file), line, *v8::String::AsciiValue(function)).debug( - "%s", qPrintable(stack)); - return v8::Undefined(); -} - -v8::Handle<v8::Value> consoleWarn(const v8::Arguments &args) -{ - return console(Warn, args); -} - -v8::Handle<v8::Value> consoleAssert(const v8::Arguments &args) -{ - if (args.Length() == 0) - V8THROW_ERROR("console.assert(): Missing argument"); - - if (!args[0]->ToBoolean()->Value()) { - QString message; - for (int i = 1; i < args.Length(); ++i) { - if (i != 1) - message.append(QLatin1Char(' ')); - - v8::Local<v8::Value> value = args[i]; - message.append(V8ENGINE()->toString(value->ToString())); - } - - QString stack = jsStack(); - - v8::Handle<v8::Value> file; - v8::Handle<v8::Value> function; - int line; - jsContext(&file, &line, &function); - - QMessageLogger(*v8::String::AsciiValue(file), line, *v8::String::AsciiValue(function)).critical( - "%s\n%s", qPrintable(message), qPrintable(stack)); - - } - return v8::Undefined(); -} - -v8::Handle<v8::Value> consoleException(const v8::Arguments &args) -{ - if (args.Length() == 0) - V8THROW_ERROR("console.exception(): Missing argument"); - - console(Error, args, true); - - return v8::Undefined(); -} - -v8::Handle<v8::Value> stringArg(const v8::Arguments &args) -{ - QString value = V8ENGINE()->toString(args.This()->ToString()); - if (args.Length() != 1) - V8THROW_ERROR("String.arg(): Invalid arguments"); - - v8::Handle<v8::Value> arg = args[0]; - if (arg->IsUint32()) - return V8ENGINE()->toString(value.arg(arg->Uint32Value())); - else if (arg->IsInt32()) - return V8ENGINE()->toString(value.arg(arg->Int32Value())); - else if (arg->IsNumber()) - return V8ENGINE()->toString(value.arg(arg->NumberValue())); - else if (arg->IsBoolean()) - return V8ENGINE()->toString(value.arg(arg->BooleanValue())); - - return V8ENGINE()->toString(value.arg(V8ENGINE()->toString(arg))); -} - -/*! -\qmlmethod bool Qt::isQtObject(object) -Returns true if \c object is a valid reference to a Qt or QML object, otherwise false. -*/ -v8::Handle<v8::Value> isQtObject(const v8::Arguments &args) -{ - if (args.Length() == 0) - return v8::Boolean::New(false); - - return v8::Boolean::New(0 != V8ENGINE()->toQObject(args[0])); -} - -/*! -\qmlmethod color Qt::rgba(real red, real green, real blue, real alpha) - -Returns a color with the specified \c red, \c green, \c blue and \c alpha components. -All components should be in the range 0-1 inclusive. -*/ -v8::Handle<v8::Value> rgba(const v8::Arguments &args) -{ - int argCount = args.Length(); - if (argCount < 3 || argCount > 4) - V8THROW_ERROR("Qt.rgba(): Invalid arguments"); - - double r = args[0]->NumberValue(); - double g = args[1]->NumberValue(); - double b = args[2]->NumberValue(); - double a = (argCount == 4) ? args[3]->NumberValue() : 1; - - if (r < 0.0) r=0.0; - if (r > 1.0) r=1.0; - if (g < 0.0) g=0.0; - if (g > 1.0) g=1.0; - if (b < 0.0) b=0.0; - if (b > 1.0) b=1.0; - if (a < 0.0) a=0.0; - if (a > 1.0) a=1.0; - - return V8ENGINE()->fromVariant(QVariant::fromValue(QColor::fromRgbF(r, g, b, a))); -} - -/*! -\qmlmethod color Qt::hsla(real hue, real saturation, real lightness, real alpha) - -Returns a color with the specified \c hue, \c saturation, \c lightness and \c alpha components. -All components should be in the range 0-1 inclusive. -*/ -v8::Handle<v8::Value> hsla(const v8::Arguments &args) -{ - int argCount = args.Length(); - if (argCount < 3 || argCount > 4) - V8THROW_ERROR("Qt.hsla(): Invalid arguments"); - - double h = args[0]->NumberValue(); - double s = args[1]->NumberValue(); - double l = args[2]->NumberValue(); - double a = (argCount == 4) ? args[3]->NumberValue() : 1; - - if (h < 0.0) h=0.0; - if (h > 1.0) h=1.0; - if (s < 0.0) s=0.0; - if (s > 1.0) s=1.0; - if (l < 0.0) l=0.0; - if (l > 1.0) l=1.0; - if (a < 0.0) a=0.0; - if (a > 1.0) a=1.0; - - return V8ENGINE()->fromVariant(QVariant::fromValue(QColor::fromHslF(h, s, l, a))); -} - -/*! -\qmlmethod rect Qt::rect(int x, int y, int width, int height) - -Returns a \c rect with the top-left corner at \c x, \c y and the specified \c width and \c height. - -The returned object has \c x, \c y, \c width and \c height attributes with the given values. -*/ -v8::Handle<v8::Value> rect(const v8::Arguments &args) -{ - if (args.Length() != 4) - V8THROW_ERROR("Qt.rect(): Invalid arguments"); - - double x = args[0]->NumberValue(); - double y = args[1]->NumberValue(); - double w = args[2]->NumberValue(); - double h = args[3]->NumberValue(); - - return V8ENGINE()->fromVariant(QVariant::fromValue(QRectF(x, y, w, h))); -} - -/*! -\qmlmethod point Qt::point(int x, int y) -Returns a Point with the specified \c x and \c y coordinates. -*/ -v8::Handle<v8::Value> point(const v8::Arguments &args) -{ - if (args.Length() != 2) - V8THROW_ERROR("Qt.point(): Invalid arguments"); - - double x = args[0]->ToNumber()->Value(); - double y = args[1]->ToNumber()->Value(); - - return V8ENGINE()->fromVariant(QVariant::fromValue(QPointF(x, y))); -} - -/*! -\qmlmethod Qt::size(int width, int height) -Returns a Size with the specified \c width and \c height. -*/ -v8::Handle<v8::Value> size(const v8::Arguments &args) -{ - if (args.Length() != 2) - V8THROW_ERROR("Qt.size(): Invalid arguments"); - - double w = args[0]->ToNumber()->Value(); - double h = args[1]->ToNumber()->Value(); - - return V8ENGINE()->fromVariant(QVariant::fromValue(QSizeF(w, h))); -} - -/*! -\qmlmethod Qt::vector3d(real x, real y, real z) -Returns a Vector3D with the specified \c x, \c y and \c z. -*/ -v8::Handle<v8::Value> vector3d(const v8::Arguments &args) -{ - if (args.Length() != 3) - V8THROW_ERROR("Qt.vector(): Invalid arguments"); - - double x = args[0]->ToNumber()->Value(); - double y = args[1]->ToNumber()->Value(); - double z = args[2]->ToNumber()->Value(); - - return V8ENGINE()->fromVariant(QVariant::fromValue(QVector3D(x, y, z))); -} - -/*! -\qmlmethod Qt::vector4d(real x, real y, real z, real w) -Returns a Vector4D with the specified \c x, \c y, \c z and \c w. -*/ -v8::Handle<v8::Value> vector4d(const v8::Arguments &args) -{ - if (args.Length() != 4) - V8THROW_ERROR("Qt.vector4d(): Invalid arguments"); - - double x = args[0]->NumberValue(); - double y = args[1]->NumberValue(); - double z = args[2]->NumberValue(); - double w = args[3]->NumberValue(); - - return V8ENGINE()->fromVariant(QVariant::fromValue(QVector4D(x, y, z, w))); -} - -/*! -\qmlmethod color Qt::lighter(color baseColor, real factor) -Returns a color lighter than \c baseColor by the \c factor provided. - -If the factor is greater than 1.0, this functions returns a lighter color. -Setting factor to 1.5 returns a color that is 50% brighter. If the factor is less than 1.0, -the return color is darker, but we recommend using the Qt.darker() function for this purpose. -If the factor is 0 or negative, the return value is unspecified. - -The function converts the current RGB color to HSV, multiplies the value (V) component -by factor and converts the color back to RGB. - -If \c factor is not supplied, returns a color 50% lighter than \c baseColor (factor 1.5). -*/ -v8::Handle<v8::Value> lighter(const v8::Arguments &args) -{ - if (args.Length() != 1 && args.Length() != 2) - V8THROW_ERROR("Qt.lighter(): Invalid arguments"); - - QColor color; - QVariant v = V8ENGINE()->toVariant(args[0], -1); - if (v.userType() == QVariant::Color) { - color = v.value<QColor>(); - } else if (v.userType() == QVariant::String) { - bool ok = false; - color = QDeclarativeStringConverters::colorFromString(v.toString(), &ok); - if (!ok) { - return v8::Null(); - } - } else { - return v8::Null(); - } - - qreal factor = 1.5; - if (args.Length() == 2) - factor = args[1]->ToNumber()->Value(); - - color = color.lighter(int(qRound(factor*100.))); - return V8ENGINE()->fromVariant(QVariant::fromValue(color)); -} - -/*! -\qmlmethod color Qt::darker(color baseColor, real factor) -Returns a color darker than \c baseColor by the \c factor provided. - -If the factor is greater than 1.0, this function returns a darker color. -Setting factor to 3.0 returns a color that has one-third the brightness. -If the factor is less than 1.0, the return color is lighter, but we recommend using -the Qt.lighter() function for this purpose. If the factor is 0 or negative, the return -value is unspecified. - -The function converts the current RGB color to HSV, divides the value (V) component -by factor and converts the color back to RGB. - -If \c factor is not supplied, returns a color 50% darker than \c baseColor (factor 2.0). -*/ -v8::Handle<v8::Value> darker(const v8::Arguments &args) -{ - if (args.Length() != 1 && args.Length() != 2) - V8THROW_ERROR("Qt.darker(): Invalid arguments"); - - QColor color; - QVariant v = V8ENGINE()->toVariant(args[0], -1); - if (v.userType() == QVariant::Color) { - color = v.value<QColor>(); - } else if (v.userType() == QVariant::String) { - bool ok = false; - color = QDeclarativeStringConverters::colorFromString(v.toString(), &ok); - if (!ok) { - return v8::Null(); - } - } else { - return v8::Null(); - } - - qreal factor = 2.0; - if (args.Length() == 2) - factor = args[1]->ToNumber()->Value(); - - color = color.darker(int(qRound(factor*100.))); - return V8ENGINE()->fromVariant(QVariant::fromValue(color)); -} - -/*! - \qmlmethod color Qt::tint(color baseColor, color tintColor) - This function allows tinting one color with another. - - The tint color should usually be mostly transparent, or you will not be - able to see the underlying color. The below example provides a slight red - tint by having the tint color be pure red which is only 1/16th opaque. - - \qml - Item { - Rectangle { - x: 0; width: 80; height: 80 - color: "lightsteelblue" - } - Rectangle { - x: 100; width: 80; height: 80 - color: Qt.tint("lightsteelblue", "#10FF0000") - } - } - \endqml - \image declarative-rect_tint.png - - Tint is most useful when a subtle change is intended to be conveyed due to some event; you can then use tinting to more effectively tune the visible color. -*/ -v8::Handle<v8::Value> tint(const v8::Arguments &args) -{ - if (args.Length() != 2) - V8THROW_ERROR("Qt.tint(): Invalid arguments"); - - // base color - QColor color; - QVariant v = V8ENGINE()->toVariant(args[0], -1); - if (v.userType() == QVariant::Color) { - color = v.value<QColor>(); - } else if (v.userType() == QVariant::String) { - bool ok = false; - color = QDeclarativeStringConverters::colorFromString(v.toString(), &ok); - if (!ok) { - return v8::Null(); - } - } else { - return v8::Null(); - } - - // tint color - QColor tintColor; - v = V8ENGINE()->toVariant(args[1], -1); - if (v.userType() == QVariant::Color) { - tintColor = v.value<QColor>(); - } else if (v.userType() == QVariant::String) { - bool ok = false; - tintColor = QDeclarativeStringConverters::colorFromString(v.toString(), &ok); - if (!ok) { - return v8::Null(); - } - } else { - return v8::Null(); - } - - // tint the base color and return the final color - QColor finalColor; - int a = tintColor.alpha(); - if (a == 0xFF) - finalColor = tintColor; - else if (a == 0x00) - finalColor = color; - else { - qreal a = tintColor.alphaF(); - qreal inv_a = 1.0 - a; - - finalColor.setRgbF(tintColor.redF() * a + color.redF() * inv_a, - tintColor.greenF() * a + color.greenF() * inv_a, - tintColor.blueF() * a + color.blueF() * inv_a, - a + inv_a * color.alphaF()); - } - - return V8ENGINE()->fromVariant(QVariant::fromValue(finalColor)); -} - -/*! -\qmlmethod string Qt::formatDate(datetime date, variant format) - -Returns a string representation of \c date, optionally formatted according -to \c format. - -The \a date parameter may be a JavaScript \c Date object, a \l{date}{date} -property, a QDate, or QDateTime value. The \a format parameter may be any of -the possible format values as described for -\l{QML:Qt::formatDateTime()}{Qt.formatDateTime()}. - -If \a format is not specified, \a date is formatted using -\l {Qt::DefaultLocaleShortDate}{Qt.DefaultLocaleShortDate}. - -\sa Locale -*/ -v8::Handle<v8::Value> formatDate(const v8::Arguments &args) -{ - if (args.Length() < 1 || args.Length() > 2) - V8THROW_ERROR("Qt.formatDate(): Invalid arguments"); - - Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate; - QDate date = V8ENGINE()->toVariant(args[0], -1).toDateTime().date(); - QString formattedDate; - if (args.Length() == 2) { - if (args[1]->IsString()) { - QString format = V8ENGINE()->toVariant(args[1], -1).toString(); - formattedDate = date.toString(format); - } else if (args[1]->IsNumber()) { - quint32 intFormat = args[1]->ToNumber()->Value(); - Qt::DateFormat format = Qt::DateFormat(intFormat); - formattedDate = date.toString(format); - } else { - V8THROW_ERROR("Qt.formatDate(): Invalid date format"); - } - } else { - formattedDate = date.toString(enumFormat); - } - - return V8ENGINE()->fromVariant(QVariant::fromValue(formattedDate)); -} - -/*! -\qmlmethod string Qt::formatTime(datetime time, variant format) - -Returns a string representation of \c time, optionally formatted according to -\c format. - -The \a time parameter may be a JavaScript \c Date object, a QTime, or QDateTime -value. The \a format parameter may be any of the possible format values as -described for \l{QML:Qt::formatDateTime()}{Qt.formatDateTime()}. - -If \a format is not specified, \a time is formatted using -\l {Qt::DefaultLocaleShortDate}{Qt.DefaultLocaleShortDate}. - -\sa Locale -*/ -v8::Handle<v8::Value> formatTime(const v8::Arguments &args) -{ - if (args.Length() < 1 || args.Length() > 2) - V8THROW_ERROR("Qt.formatTime(): Invalid arguments"); - - QVariant argVariant = V8ENGINE()->toVariant(args[0], -1); - QTime time; - if (args[0]->IsDate() || (argVariant.type() == QVariant::String)) - time = argVariant.toDateTime().time(); - else // if (argVariant.type() == QVariant::Time), or invalid. - time = argVariant.toTime(); - - Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate; - QString formattedTime; - if (args.Length() == 2) { - if (args[1]->IsString()) { - QString format = V8ENGINE()->toVariant(args[1], -1).toString(); - formattedTime = time.toString(format); - } else if (args[1]->IsNumber()) { - quint32 intFormat = args[1]->ToNumber()->Value(); - Qt::DateFormat format = Qt::DateFormat(intFormat); - formattedTime = time.toString(format); - } else { - V8THROW_ERROR("Qt.formatTime(): Invalid time format"); - } - } else { - formattedTime = time.toString(enumFormat); - } - - return V8ENGINE()->fromVariant(QVariant::fromValue(formattedTime)); -} - -/*! -\qmlmethod string Qt::formatDateTime(datetime dateTime, variant format) - -Returns a string representation of \c datetime, optionally formatted according to -\c format. - -The \a date parameter may be a JavaScript \c Date object, a \l{date}{date} -property, a QDate, QTime, or QDateTime value. - -If \a format is not provided, \a dateTime is formatted using -\l {Qt::DefaultLocaleShortDate}{Qt.DefaultLocaleShortDate}. Otherwise, -\a format should be either: - -\list -\o One of the Qt::DateFormat enumeration values, such as - \c Qt.DefaultLocaleShortDate or \c Qt.ISODate -\o A string that specifies the format of the returned string, as detailed below. -\endlist - -If \a format specifies a format string, it should use the following expressions -to specify the date: - - \table - \header \i Expression \i Output - \row \i d \i the day as number without a leading zero (1 to 31) - \row \i dd \i the day as number with a leading zero (01 to 31) - \row \i ddd - \i the abbreviated localized day name (e.g. 'Mon' to 'Sun'). - Uses QDate::shortDayName(). - \row \i dddd - \i the long localized day name (e.g. 'Monday' to 'Qt::Sunday'). - Uses QDate::longDayName(). - \row \i M \i the month as number without a leading zero (1-12) - \row \i MM \i the month as number with a leading zero (01-12) - \row \i MMM - \i the abbreviated localized month name (e.g. 'Jan' to 'Dec'). - Uses QDate::shortMonthName(). - \row \i MMMM - \i the long localized month name (e.g. 'January' to 'December'). - Uses QDate::longMonthName(). - \row \i yy \i the year as two digit number (00-99) - \row \i yyyy \i the year as four digit number - \endtable - -In addition the following expressions can be used to specify the time: - - \table - \header \i Expression \i Output - \row \i h - \i the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display) - \row \i hh - \i the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display) - \row \i m \i the minute without a leading zero (0 to 59) - \row \i mm \i the minute with a leading zero (00 to 59) - \row \i s \i the second without a leading zero (0 to 59) - \row \i ss \i the second with a leading zero (00 to 59) - \row \i z \i the milliseconds without leading zeroes (0 to 999) - \row \i zzz \i the milliseconds with leading zeroes (000 to 999) - \row \i AP - \i use AM/PM display. \e AP will be replaced by either "AM" or "PM". - \row \i ap - \i use am/pm display. \e ap will be replaced by either "am" or "pm". - \endtable - - All other input characters will be ignored. Any sequence of characters that - are enclosed in single quotes will be treated as text and not be used as an - expression. Two consecutive single quotes ("''") are replaced by a single quote - in the output. - -For example, if the following date/time value was specified: - - \code - // 21 May 2001 14:13:09 - var dateTime = new Date(2001, 5, 21, 14, 13, 09) - \endcode - -This \a dateTime value could be passed to \c Qt.formatDateTime(), -\l {QML:Qt::formatDate()}{Qt.formatDate()} or \l {QML:Qt::formatTime()}{Qt.formatTime()} -with the \a format values below to produce the following results: - - \table - \header \i Format \i Result - \row \i "dd.MM.yyyy" \i 21.05.2001 - \row \i "ddd MMMM d yy" \i Tue May 21 01 - \row \i "hh:mm:ss.zzz" \i 14:13:09.042 - \row \i "h:m:s ap" \i 2:13:9 pm - \endtable - - \sa Locale -*/ -v8::Handle<v8::Value> formatDateTime(const v8::Arguments &args) -{ - if (args.Length() < 1 || args.Length() > 2) - V8THROW_ERROR("Qt.formatDateTime(): Invalid arguments"); - - Qt::DateFormat enumFormat = Qt::DefaultLocaleShortDate; - QDateTime dt = V8ENGINE()->toVariant(args[0], -1).toDateTime(); - QString formattedDt; - if (args.Length() == 2) { - if (args[1]->IsString()) { - QString format = V8ENGINE()->toVariant(args[1], -1).toString(); - formattedDt = dt.toString(format); - } else if (args[1]->IsNumber()) { - quint32 intFormat = args[1]->ToNumber()->Value(); - Qt::DateFormat format = Qt::DateFormat(intFormat); - formattedDt = dt.toString(format); - } else { - V8THROW_ERROR("Qt.formatDateTime(): Invalid datetime format"); - } - } else { - formattedDt = dt.toString(enumFormat); - } - - return V8ENGINE()->fromVariant(QVariant::fromValue(formattedDt)); -} - -/*! -\qmlmethod bool Qt::openUrlExternally(url target) -Attempts to open the specified \c target url in an external application, based on the user's desktop preferences. Returns true if it succeeds, and false otherwise. -*/ -v8::Handle<v8::Value> openUrlExternally(const v8::Arguments &args) -{ - if (args.Length() != 1) - return V8ENGINE()->fromVariant(false); - - bool ret = false; -#ifndef QT_NO_DESKTOPSERVICES - ret = QDesktopServices::openUrl(V8ENGINE()->toVariant(resolvedUrl(args), -1).toUrl()); -#endif - return V8ENGINE()->fromVariant(ret); -} - -/*! - \qmlmethod url Qt::resolvedUrl(url url) - Returns \a url resolved relative to the URL of the caller. -*/ -v8::Handle<v8::Value> resolvedUrl(const v8::Arguments &args) -{ - QUrl url = V8ENGINE()->toVariant(args[0], -1).toUrl(); - QDeclarativeEngine *e = V8ENGINE()->engine(); - QDeclarativeEnginePrivate *p = 0; - if (e) p = QDeclarativeEnginePrivate::get(e); - if (p) { - QDeclarativeContextData *ctxt = V8ENGINE()->callingContext(); - if (ctxt) - return V8ENGINE()->toString(ctxt->resolvedUrl(url).toString()); - else - return V8ENGINE()->toString(url.toString()); - } - - return V8ENGINE()->toString(e->baseUrl().resolved(url).toString()); -} - -/*! -\qmlmethod list<string> Qt::fontFamilies() -Returns a list of the font families available to the application. -*/ -v8::Handle<v8::Value> fontFamilies(const v8::Arguments &args) -{ - if (args.Length() != 0) - V8THROW_ERROR("Qt.fontFamilies(): Invalid arguments"); - - QFontDatabase database; - return V8ENGINE()->fromVariant(database.families()); -} - -/*! -\qmlmethod string Qt::md5(data) -Returns a hex string of the md5 hash of \c data. -*/ -v8::Handle<v8::Value> md5(const v8::Arguments &args) -{ - if (args.Length() != 1) - V8THROW_ERROR("Qt.md5(): Invalid arguments"); - - QByteArray data = V8ENGINE()->toString(args[0]->ToString()).toUtf8(); - QByteArray result = QCryptographicHash::hash(data, QCryptographicHash::Md5); - return V8ENGINE()->toString(QLatin1String(result.toHex())); -} - -/*! -\qmlmethod string Qt::btoa(data) -Binary to ASCII - this function returns a base64 encoding of \c data. -*/ -v8::Handle<v8::Value> btoa(const v8::Arguments &args) -{ - if (args.Length() != 1) - V8THROW_ERROR("Qt.btoa(): Invalid arguments"); - - QByteArray data = V8ENGINE()->toString(args[0]->ToString()).toUtf8(); - - return V8ENGINE()->toString(QLatin1String(data.toBase64())); -} - -/*! -\qmlmethod string Qt::atob(data) -ASCII to binary - this function returns a base64 decoding of \c data. -*/ -v8::Handle<v8::Value> atob(const v8::Arguments &args) -{ - if (args.Length() != 1) - V8THROW_ERROR("Qt.atob(): Invalid arguments"); - - QByteArray data = V8ENGINE()->toString(args[0]->ToString()).toUtf8(); - - return V8ENGINE()->toString(QLatin1String(QByteArray::fromBase64(data))); -} - -/*! -\qmlmethod Qt::quit() -This function causes the QDeclarativeEngine::quit() signal to be emitted. -Within the \l {QML Viewer}, this causes the launcher application to exit; -to quit a C++ application when this method is called, connect the -QDeclarativeEngine::quit() signal to the QCoreApplication::quit() slot. -*/ -v8::Handle<v8::Value> quit(const v8::Arguments &args) -{ - QDeclarativeEnginePrivate::get(V8ENGINE()->engine())->sendQuit(); - return v8::Undefined(); -} - -/*! -\qmlmethod object Qt::createQmlObject(string qml, object parent, string filepath) - -Returns a new object created from the given \a string of QML which will have the specified \a parent, -or \c null if there was an error in creating the object. - -If \a filepath is specified, it will be used for error reporting for the created object. - -Example (where \c parentItem is the id of an existing QML item): - -\snippet doc/src/snippets/declarative/createQmlObject.qml 0 - -In the case of an error, a QtScript Error object is thrown. This object has an additional property, -\c qmlErrors, which is an array of the errors encountered. -Each object in this array has the members \c lineNumber, \c columnNumber, \c fileName and \c message. -For example, if the above snippet had misspelled color as 'colro' then the array would contain an object like the following: -{ "lineNumber" : 1, "columnNumber" : 32, "fileName" : "dynamicSnippet1", "message" : "Cannot assign to non-existent property \"colro\""}. - -Note that this function returns immediately, and therefore may not work if -the \a qml string loads new components (that is, external QML files that have not yet been loaded). -If this is the case, consider using \l{QML:Qt::createComponent()}{Qt.createComponent()} instead. - -See \l {Dynamic Object Management in QML} for more information on using this function. -*/ -v8::Handle<v8::Value> createQmlObject(const v8::Arguments &args) -{ - if (args.Length() < 2 || args.Length() > 3) - V8THROW_ERROR("Qt.createQmlObject(): Invalid arguments"); - - struct Error { - static v8::Local<v8::Value> create(QV8Engine *engine, const QList<QDeclarativeError> &errors) { - QString errorstr = QLatin1String("Qt.createQmlObject(): failed to create object: "); - - v8::Local<v8::Array> qmlerrors = v8::Array::New(errors.count()); - for (int ii = 0; ii < errors.count(); ++ii) { - const QDeclarativeError &error = errors.at(ii); - errorstr += QLatin1String("\n ") + error.toString(); - v8::Local<v8::Object> qmlerror = v8::Object::New(); - qmlerror->Set(v8::String::New("lineNumber"), v8::Integer::New(error.line())); - qmlerror->Set(v8::String::New("columnNumber"), v8::Integer::New(error.column())); - qmlerror->Set(v8::String::New("fileName"), engine->toString(error.url().toString())); - qmlerror->Set(v8::String::New("message"), engine->toString(error.description())); - qmlerrors->Set(ii, qmlerror); - } - - v8::Local<v8::Value> error = v8::Exception::Error(engine->toString(errorstr)); - v8::Local<v8::Object> errorObject = error->ToObject(); - errorObject->Set(v8::String::New("qmlErrors"), qmlerrors); - return error; - } - }; - - QV8Engine *v8engine = V8ENGINE(); - QDeclarativeEngine *engine = v8engine->engine(); - - QDeclarativeContextData *context = v8engine->callingContext(); - QDeclarativeContext *effectiveContext = 0; - if (context->isPragmaLibraryContext) - effectiveContext = engine->rootContext(); - else - effectiveContext = context->asQDeclarativeContext(); - Q_ASSERT(context && effectiveContext); - - QString qml = v8engine->toString(args[0]->ToString()); - if (qml.isEmpty()) - return v8::Null(); - - QUrl url; - if (args.Length() > 2) - url = QUrl(v8engine->toString(args[2]->ToString())); - else - url = QUrl(QLatin1String("inline")); - - if (url.isValid() && url.isRelative()) - url = context->resolvedUrl(url); - - QObject *parentArg = v8engine->toQObject(args[1]); - if (!parentArg) - V8THROW_ERROR("Qt.createQmlObject(): Missing parent object"); - - QDeclarativeComponent component(engine); - component.setData(qml.toUtf8(), url); - - if (component.isError()) { - v8::ThrowException(Error::create(v8engine, component.errors())); - return v8::Undefined(); - } - - if (!component.isReady()) - V8THROW_ERROR("Qt.createQmlObject(): Component is not ready"); - - QObject *obj = component.beginCreate(effectiveContext); - if (obj) - QDeclarativeData::get(obj, true)->setImplicitDestructible(); - component.completeCreate(); - - if (component.isError()) { - v8::ThrowException(Error::create(v8engine, component.errors())); - return v8::Undefined(); - } - - Q_ASSERT(obj); - - obj->setParent(parentArg); - - QList<QDeclarativePrivate::AutoParentFunction> functions = QDeclarativeMetaType::parentFunctions(); - for (int ii = 0; ii < functions.count(); ++ii) { - if (QDeclarativePrivate::Parented == functions.at(ii)(obj, parentArg)) - break; - } - - return v8engine->newQObject(obj); -} - -/*! -\qmlmethod object Qt::createComponent(url) - -Returns a \l Component object created using the QML file at the specified \a url, -or \c null if an empty string was given. - -The returned component's \l Component::status property indicates whether the -component was successfully created. If the status is \c Component.Error, -see \l Component::errorString() for an error description. - -Call \l {Component::createObject()}{Component.createObject()} on the returned -component to create an object instance of the component. - -For example: - -\snippet doc/src/snippets/declarative/createComponent-simple.qml 0 - -See \l {Dynamic Object Management in QML} for more information on using this function. - -To create a QML object from an arbitrary string of QML (instead of a file), -use \l{QML:Qt::createQmlObject()}{Qt.createQmlObject()}. -*/ -v8::Handle<v8::Value> createComponent(const v8::Arguments &args) -{ - if (args.Length() != 1) - V8THROW_ERROR("Qt.createComponent(): Invalid arguments"); - - QV8Engine *v8engine = V8ENGINE(); - QDeclarativeEngine *engine = v8engine->engine(); - - QDeclarativeContextData *context = v8engine->callingContext(); - QDeclarativeContextData *effectiveContext = context; - if (context->isPragmaLibraryContext) - effectiveContext = 0; - Q_ASSERT(context); - - QString arg = v8engine->toString(args[0]->ToString()); - if (arg.isEmpty()) - return v8::Null(); - - QUrl url = context->resolvedUrl(QUrl(arg)); - QDeclarativeComponent *c = new QDeclarativeComponent(engine, url, engine); - QDeclarativeComponentPrivate::get(c)->creationContext = effectiveContext; - QDeclarativeData::get(c, true)->setImplicitDestructible(); - return v8engine->newQObject(c); -} - -v8::Handle<v8::Value> qsTranslate(const v8::Arguments &args) -{ - if (args.Length() < 2) - V8THROW_ERROR("qsTranslate() requires at least two arguments"); - if (!args[0]->IsString()) - V8THROW_ERROR("qsTranslate(): first argument (context) must be a string"); - if (!args[1]->IsString()) - V8THROW_ERROR("qsTranslate(): second argument (text) must be a string"); - if ((args.Length() > 2) && !args[2]->IsString()) - V8THROW_ERROR("qsTranslate(): third argument (comment) must be a string"); - if ((args.Length() > 3) && !args[3]->IsString()) - V8THROW_ERROR("qsTranslate(): fourth argument (encoding) must be a string"); - - QV8Engine *v8engine = V8ENGINE(); - QString context = v8engine->toString(args[0]); - QString text = v8engine->toString(args[1]); - QString comment; - if (args.Length() > 2) comment = v8engine->toString(args[2]); - - QCoreApplication::Encoding encoding = QCoreApplication::UnicodeUTF8; - if (args.Length() > 3) { - QString encStr = v8engine->toString(args[3]); - if (encStr == QLatin1String("CodecForTr")) { - encoding = QCoreApplication::CodecForTr; - } else if (encStr == QLatin1String("UnicodeUTF8")) { - encoding = QCoreApplication::UnicodeUTF8; - } else { - QString msg = QString::fromLatin1("qsTranslate(): invalid encoding '%0'").arg(encStr); - V8THROW_ERROR((uint16_t *)msg.constData()); - } - } - - int n = -1; - if (args.Length() > 4) - n = args[4]->Int32Value(); - - QString result = QCoreApplication::translate(context.toUtf8().constData(), - text.toUtf8().constData(), - comment.toUtf8().constData(), - encoding, n); - - return v8engine->toString(result); -} - -v8::Handle<v8::Value> qsTranslateNoOp(const v8::Arguments &args) -{ - if (args.Length() < 2) - return v8::Undefined(); - return args[1]; -} - -v8::Handle<v8::Value> qsTr(const v8::Arguments &args) -{ - if (args.Length() < 1) - V8THROW_ERROR("qsTr() requires at least one argument"); - if (!args[0]->IsString()) - V8THROW_ERROR("qsTr(): first argument (text) must be a string"); - if ((args.Length() > 1) && !args[1]->IsString()) - V8THROW_ERROR("qsTr(): second argument (comment) must be a string"); - if ((args.Length() > 2) && !args[2]->IsNumber()) - V8THROW_ERROR("qsTr(): third argument (n) must be a number"); - - QV8Engine *v8engine = V8ENGINE(); - QDeclarativeContextData *ctxt = v8engine->callingContext(); - - QString path = ctxt->url.toString(); - int lastSlash = path.lastIndexOf(QLatin1Char('/')); - QString context = (lastSlash > -1) ? path.mid(lastSlash + 1, path.length()-lastSlash-5) : QString(); - - QString text = v8engine->toString(args[0]); - QString comment; - if (args.Length() > 1) - comment = v8engine->toString(args[1]); - int n = -1; - if (args.Length() > 2) - n = args[2]->Int32Value(); - - QString result = QCoreApplication::translate(context.toUtf8().constData(), text.toUtf8().constData(), - comment.toUtf8().constData(), QCoreApplication::UnicodeUTF8, n); - - return v8engine->toString(result); -} - -v8::Handle<v8::Value> qsTrNoOp(const v8::Arguments &args) -{ - if (args.Length() < 1) - return v8::Undefined(); - return args[0]; -} - -v8::Handle<v8::Value> qsTrId(const v8::Arguments &args) -{ - if (args.Length() < 1) - V8THROW_ERROR("qsTrId() requires at least one argument"); - if (!args[0]->IsString()) - V8THROW_TYPE("qsTrId(): first argument (id) must be a string"); - if (args.Length() > 1 && !args[1]->IsNumber()) - V8THROW_TYPE("qsTrId(): second argument (n) must be a number"); - - int n = -1; - if (args.Length() > 1) - n = args[1]->Int32Value(); - - QV8Engine *v8engine = V8ENGINE(); - return v8engine->toString(qtTrId(v8engine->toString(args[0]).toUtf8().constData(), n)); -} - -v8::Handle<v8::Value> qsTrIdNoOp(const v8::Arguments &args) -{ - if (args.Length() < 1) - return v8::Undefined(); - return args[0]; -} - - -/*! - \qmlmethod Qt::locale(name) - - Returns a JS object representing the locale with the specified - name, which has the format "language[_territory][.codeset][@modifier]" - or "C", where: - - \list - \o language is a lowercase, two-letter, ISO 639 language code, - \o territory is an uppercase, two-letter, ISO 3166 country code, - \o and codeset and modifier are ignored. - \endlist - - If the string violates the locale format, or language is not a - valid ISO 369 code, the "C" locale is used instead. If country - is not present, or is not a valid ISO 3166 code, the most - appropriate country is chosen for the specified language. - - \sa QtQuick2::Locale -*/ -v8::Handle<v8::Value> locale(const v8::Arguments &args) -{ - QString code; - if (args.Length() > 1) - V8THROW_ERROR("locale() requires 0 or 1 argument"); - if (args.Length() == 1 && !args[0]->IsString()) - V8THROW_TYPE("locale(): argument (locale code) must be a string"); - - QV8Engine *v8engine = V8ENGINE(); - if (args.Length() == 1) - code = v8engine->toString(args[0]); - - return QDeclarativeLocale::locale(v8engine, code); -} - -} // namespace QDeclarativeBuiltinFunctions - -QT_END_NAMESPACE diff --git a/src/declarative/qml/v8/qdeclarativebuiltinfunctions_p.h b/src/declarative/qml/v8/qdeclarativebuiltinfunctions_p.h deleted file mode 100644 index d5780dc70d..0000000000 --- a/src/declarative/qml/v8/qdeclarativebuiltinfunctions_p.h +++ /dev/null @@ -1,110 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QDECLARATIVEBUILTINFUNCTIONS_P_H -#define QDECLARATIVEBUILTINFUNCTIONS_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/qglobal.h> -#include <private/qv8_p.h> - -QT_BEGIN_NAMESPACE - -namespace QDeclarativeBuiltinFunctions -{ -v8::Handle<v8::Value> gc(const v8::Arguments &args); -v8::Handle<v8::Value> consoleError(const v8::Arguments &args); -v8::Handle<v8::Value> consoleLog(const v8::Arguments &args); -v8::Handle<v8::Value> consoleProfile(const v8::Arguments &args); -v8::Handle<v8::Value> consoleProfileEnd(const v8::Arguments &args); -v8::Handle<v8::Value> consoleTime(const v8::Arguments &args); -v8::Handle<v8::Value> consoleTimeEnd(const v8::Arguments &args); -v8::Handle<v8::Value> consoleCount(const v8::Arguments &args); -v8::Handle<v8::Value> consoleTrace(const v8::Arguments &args); -v8::Handle<v8::Value> consoleWarn(const v8::Arguments &args); -v8::Handle<v8::Value> consoleAssert(const v8::Arguments &args); -v8::Handle<v8::Value> consoleException(const v8::Arguments &args); -v8::Handle<v8::Value> isQtObject(const v8::Arguments &args); -v8::Handle<v8::Value> rgba(const v8::Arguments &args); -v8::Handle<v8::Value> hsla(const v8::Arguments &args); -v8::Handle<v8::Value> rect(const v8::Arguments &args); -v8::Handle<v8::Value> point(const v8::Arguments &args); -v8::Handle<v8::Value> size(const v8::Arguments &args); -v8::Handle<v8::Value> vector3d(const v8::Arguments &args); -v8::Handle<v8::Value> vector4d(const v8::Arguments &args); -v8::Handle<v8::Value> lighter(const v8::Arguments &args); -v8::Handle<v8::Value> darker(const v8::Arguments &args); -v8::Handle<v8::Value> tint(const v8::Arguments &args); -v8::Handle<v8::Value> formatDate(const v8::Arguments &args); -v8::Handle<v8::Value> formatTime(const v8::Arguments &args); -v8::Handle<v8::Value> formatDateTime(const v8::Arguments &args); -v8::Handle<v8::Value> openUrlExternally(const v8::Arguments &args); -v8::Handle<v8::Value> fontFamilies(const v8::Arguments &args); -v8::Handle<v8::Value> md5(const v8::Arguments &args); -v8::Handle<v8::Value> btoa(const v8::Arguments &args); -v8::Handle<v8::Value> atob(const v8::Arguments &args); -v8::Handle<v8::Value> quit(const v8::Arguments &args); -v8::Handle<v8::Value> resolvedUrl(const v8::Arguments &args); -v8::Handle<v8::Value> createQmlObject(const v8::Arguments &args); -v8::Handle<v8::Value> createComponent(const v8::Arguments &args); -v8::Handle<v8::Value> qsTranslate(const v8::Arguments &args); -v8::Handle<v8::Value> qsTranslateNoOp(const v8::Arguments &args); -v8::Handle<v8::Value> qsTr(const v8::Arguments &args); -v8::Handle<v8::Value> qsTrNoOp(const v8::Arguments &args); -v8::Handle<v8::Value> qsTrId(const v8::Arguments &args); -v8::Handle<v8::Value> qsTrIdNoOp(const v8::Arguments &args); -v8::Handle<v8::Value> stringArg(const v8::Arguments &args); -v8::Handle<v8::Value> locale(const v8::Arguments &args); -} - -QT_END_NAMESPACE - -#endif // QDECLARATIVEBUILTINFUNCTIONS_P_H diff --git a/src/declarative/qml/v8/qjsconverter_impl_p.h b/src/declarative/qml/v8/qjsconverter_impl_p.h deleted file mode 100644 index 018c0441a2..0000000000 --- a/src/declarative/qml/v8/qjsconverter_impl_p.h +++ /dev/null @@ -1,268 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qjsconverter_p.h" - -#ifndef QJSCONVERTER_IMPL_P_H -#define QJSCONVERTER_IMPL_P_H - -QT_BEGIN_NAMESPACE - -extern char *qdtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **digits_str); -Q_CORE_EXPORT QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax); - - -quint32 QJSConverter::toArrayIndex(const QString& string) -{ - // FIXME this function should be exported by JSC C API. - bool ok; - quint32 idx = string.toUInt(&ok); - if (!ok || toString(idx) != string) - idx = 0xffffffff; - - return idx; -} - -QString QJSConverter::toString(v8::Handle<v8::String> jsString) -{ - if (jsString.IsEmpty()) - return QString(); - QString qstr; - qstr.resize(jsString->Length()); - jsString->Write(reinterpret_cast<uint16_t*>(qstr.data())); - return qstr; -} - -v8::Local<v8::String> QJSConverter::toString(const QString& string) -{ - return v8::String::New(reinterpret_cast<const uint16_t*>(string.data()), string.size()); -} - -QString QJSConverter::toString(double value) -{ - // FIXME this should be easier. The ideal fix is to create - // a new function in V8 API which could cover the functionality. - - if (qIsNaN(value)) - return QString::fromLatin1("NaN"); - if (qIsInf(value)) - return QString::fromLatin1(value < 0 ? "-Infinity" : "Infinity"); - if (!value) - return QString::fromLatin1("0"); - - QVarLengthArray<char, 25> buf; - int decpt; - int sign; - char* result = 0; - char* endresult; - (void)qdtoa(value, 0, 0, &decpt, &sign, &endresult, &result); - - if (!result) - return QString(); - - int resultLen = endresult - result; - if (decpt <= 0 && decpt > -6) { - buf.resize(-decpt + 2 + sign); - qMemSet(buf.data(), '0', -decpt + 2 + sign); - if (sign) // fix the sign. - buf[0] = '-'; - buf[sign + 1] = '.'; - buf.append(result, resultLen); - } else { - if (sign) - buf.append('-'); - int length = buf.size() - sign + resultLen; - if (decpt <= 21 && decpt > 0) { - if (length <= decpt) { - const char* zeros = "0000000000000000000000000"; - buf.append(result, resultLen); - buf.append(zeros, decpt - length); - } else { - buf.append(result, decpt); - buf.append('.'); - buf.append(result + decpt, resultLen - decpt); - } - } else if (result[0] >= '0' && result[0] <= '9') { - if (length > 1) { - buf.append(result, 1); - buf.append('.'); - buf.append(result + 1, resultLen - 1); - } else - buf.append(result, resultLen); - buf.append('e'); - buf.append(decpt >= 0 ? '+' : '-'); - int e = qAbs(decpt - 1); - if (e >= 100) - buf.append('0' + e / 100); - if (e >= 10) - buf.append('0' + (e % 100) / 10); - buf.append('0' + e % 10); - } - } - free(result); - buf.append(0); - 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. -QRegExp QJSConverter::toRegExp(v8::Handle<v8::RegExp> jsRegExp) -{ - QString pattern = QJSConverter::toString(jsRegExp->GetSource()); - Qt::CaseSensitivity caseSensitivity = Qt::CaseSensitive; - if (jsRegExp->GetFlags() & v8::RegExp::kIgnoreCase) - caseSensitivity = Qt::CaseInsensitive; - return QRegExp(pattern, caseSensitivity, QRegExp::RegExp2); -} - -// 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. -v8::Local<v8::RegExp> QJSConverter::toRegExp(const QRegExp &re) -{ - // Convert the pattern to a ECMAScript pattern. - QString pattern = qt_regexp_toCanonical(re.pattern(), re.patternSyntax()); - if (re.isMinimal()) { - QString ecmaPattern; - int len = pattern.length(); - ecmaPattern.reserve(len); - int i = 0; - const QChar *wc = pattern.unicode(); - bool inBracket = false; - while (i < len) { - QChar c = wc[i++]; - ecmaPattern += c; - switch (c.unicode()) { - case '?': - case '+': - case '*': - case '}': - if (!inBracket) - ecmaPattern += QLatin1Char('?'); - break; - case '\\': - if (i < len) - ecmaPattern += wc[i++]; - break; - case '[': - inBracket = true; - break; - case ']': - inBracket = false; - break; - default: - break; - } - } - pattern = ecmaPattern; - } - - int flags = v8::RegExp::kNone; - if (re.caseSensitivity() == Qt::CaseInsensitive) - flags |= v8::RegExp::kIgnoreCase; - - return v8::RegExp::New(QJSConverter::toString(pattern), static_cast<v8::RegExp::Flags>(flags)); -} - -// 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. -v8::Local<v8::Array> QJSConverter::toStringList(const QStringList &lst) -{ - v8::Local<v8::Array> result = v8::Array::New(lst.size()); - for (int i = 0; i < lst.size(); ++i) - result->Set(i, toString(lst.at(i))); - return result; -} - -// 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. -QStringList QJSConverter::toStringList(v8::Handle<v8::Array> jsArray) -{ - QStringList result; - uint32_t length = jsArray->Length(); - for (uint32_t i = 0; i < length; ++i) - result.append(toString(jsArray->Get(i)->ToString())); - return result; -} - - -// Converts a JS Date to a QDateTime. -QDateTime QJSConverter::toDateTime(v8::Handle<v8::Date> jsDate) -{ - return QDateTime::fromMSecsSinceEpoch(jsDate->NumberValue()); -} - -// Converts a QDateTime to a JS Date. -v8::Local<v8::Value> QJSConverter::toDateTime(const QDateTime &dt) -{ - double date; - if (!dt.isValid()) - date = qSNaN(); - else - date = dt.toMSecsSinceEpoch(); - return v8::Date::New(date); -} - -QT_END_NAMESPACE - -#endif // QJSCONVERTER_IMPL_P_H diff --git a/src/declarative/qml/v8/qjsconverter_p.h b/src/declarative/qml/v8/qjsconverter_p.h deleted file mode 100644 index 29fef3c700..0000000000 --- a/src/declarative/qml/v8/qjsconverter_p.h +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtScript module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL-ONLY$ -** GNU Lesser General Public License Usage -** 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. -** -** If you have questions regarding the use of this file, please contact -** us via http://www.qt-project.org/. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QJSCONVERTER_P_H -#define QJSCONVERTER_P_H - -#include "qjsvalue_p.h" -#include <QtCore/qglobal.h> -#include <QtCore/qnumeric.h> -#include <QtCore/qstring.h> -#include <QtCore/qstringlist.h> -#include <QtCore/qvarlengtharray.h> -#include <QtCore/qregexp.h> -#include <QtCore/qdatetime.h> - -#include <private/qv8_p.h> - -QT_BEGIN_NAMESPACE - -/* - \internal - \class QJSConverter - QJSValue and QJSEngine helper class. This class's responsibility is to convert values - between JS values and Qt/C++ values. - - This is a nice way to inline these functions in both QJSValue and QJSEngine. -*/ -class QJSConverter { -public: - static inline 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); - - 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); - - // 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); - - // 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); - - // 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); - - // Converts a JS Date to a QDateTime. - static inline QDateTime toDateTime(v8::Handle<v8::Date> jsDate); - - // Converts a QDateTime to a JS Date. - static inline v8::Local<v8::Value> toDateTime(const QDateTime &dt); -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/declarative/qml/v8/qjsengine.cpp b/src/declarative/qml/v8/qjsengine.cpp deleted file mode 100644 index 3121d1b361..0000000000 --- a/src/declarative/qml/v8/qjsengine.cpp +++ /dev/null @@ -1,476 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtScript module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL-ONLY$ -** GNU Lesser General Public License Usage -** 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. -** -** If you have questions regarding the use of this file, please contact -** us via http://www.qt-project.org/. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qjsengine.h" -#include "qjsengine_p.h" -#include "qjsvalue.h" -#include "qjsvalue_p.h" -#include "qscriptisolate_p.h" -#include "qscript_impl_p.h" -#include "qv8engine_p.h" - -#include <QtCore/qdatetime.h> -#include <QtCore/qmetaobject.h> -#include <QtCore/qstringlist.h> -#include <QtCore/qvariant.h> -#include <QtCore/qdatetime.h> - -#include <QtCore/qcoreapplication.h> -#include <QtCore/qdir.h> -#include <QtCore/qfile.h> -#include <QtCore/qfileinfo.h> -#include <QtCore/qpluginloader.h> -#include <qthread.h> -#include <qmutex.h> -#include <qwaitcondition.h> - -#undef Q_D -#undef Q_Q -#define Q_D(blah) -#define Q_Q(blah) - -Q_DECLARE_METATYPE(QJSValue) -Q_DECLARE_METATYPE(QObjectList) -Q_DECLARE_METATYPE(QList<int>) - -/*! - \since 5.0 - \class QJSEngine - - \brief The QJSEngine class provides an environment for evaluating JavaScript code. - - \ingroup qtjavascript - \mainclass - - \section1 Evaluating Scripts - - Use evaluate() to evaluate script code. - - \snippet doc/src/snippets/code/src_script_qjsengine.cpp 0 - - evaluate() returns a QJSValue that holds the result of the - evaluation. The QJSValue class provides functions for converting - the result to various C++ types (e.g. QJSValue::toString() - and QJSValue::toNumber()). - - The following code snippet shows how a script function can be - defined and then invoked from C++ using QJSValue::call(): - - \snippet doc/src/snippets/code/src_script_qjsengine.cpp 1 - - As can be seen from the above snippets, a script is provided to the - engine in the form of a string. One common way of loading scripts is - by reading the contents of a file and passing it to evaluate(): - - \snippet doc/src/snippets/code/src_script_qjsengine.cpp 2 - - Here we pass the name of the file as the second argument to - evaluate(). This does not affect evaluation in any way; the second - argument is a general-purpose string that is used to identify the - script for debugging purposes (for example, our filename will now - show up in any uncaughtExceptionBacktrace() involving the script). - - \section1 Engine Configuration - - The globalObject() function returns the \bold {Global Object} - associated with the script engine. Properties of the Global Object - are accessible from any script code (i.e. they are global - variables). Typically, before evaluating "user" scripts, you will - want to configure a script engine by adding one or more properties - to the Global Object: - - \snippet doc/src/snippets/code/src_script_qjsengine.cpp 3 - - Adding custom properties to the scripting environment is one of the - standard means of providing a scripting API that is specific to your - application. Usually these custom properties are objects created by - the newQObject() or newObject() functions. - - \section1 Script Exceptions - - evaluate() can throw a script exception (e.g. due to a syntax - error); in that case, the return value is the value that was thrown - (typically an \c{Error} object). You can check whether the - evaluation caused an exception by calling hasUncaughtException(). In - that case, you can call toString() on the error object to obtain an - error message. The current uncaught exception is also available - through uncaughtException(). - Calling clearExceptions() will cause any uncaught exceptions to be - cleared. - - \snippet doc/src/snippets/code/src_script_qjsengine.cpp 4 - - \section1 Script Object Creation - - Use newObject() to create a JavaScript object; this is the - C++ equivalent of the script statement \c{new Object()}. You can use - the object-specific functionality in QJSValue to manipulate the - script object (e.g. QJSValue::setProperty()). Similarly, use - newArray() to create a JavaScript array object. - - \section1 QObject Integration - - Use newQObject() to wrap a QObject (or subclass) - pointer. newQObject() returns a proxy script object; properties, - children, and signals and slots of the QObject are available as - properties of the proxy object. No binding code is needed because it - is done dynamically using the Qt meta object system. - - \snippet doc/src/snippets/code/src_script_qjsengine.cpp 5 - - \sa QJSValue, {Making Applications Scriptable} - -*/ - -QT_BEGIN_NAMESPACE - - -/*! - Constructs a QJSEngine object. - - The globalObject() is initialized to have properties as described in - \l{ECMA-262}, Section 15.1. -*/ -QJSEngine::QJSEngine() - : d(new QV8Engine(this)) -{ -} - -#ifdef QT_DEPRECATED - -/*! - \internal -*/ -QJSEngine::QJSEngine(QJSEngine::ContextOwnership ownership) - : d(new QV8Engine(this, ownership)) -{ -} - -#endif // QT_DEPRECATED - -/*! - Constructs a QJSEngine object with the given \a parent. - - The globalObject() is initialized to have properties as described in - \l{ECMA-262}, Section 15.1. -*/ - -QJSEngine::QJSEngine(QObject *parent) - : QObject(parent) - , d(new QV8Engine(this)) -{ -} - -QJSEngine::QJSEngine(QJSEnginePrivate &dd, QObject *parent) - : QObject(dd, parent) - , d(new QV8Engine(this)) -{ -} - -/*! - Destroys this QJSEngine. -*/ -QJSEngine::~QJSEngine() -{ - delete d; -} - -/*! - \fn QV8Engine *QJSEngine::handle() const - \internal -*/ - -#ifdef QT_DEPRECATED - -/*! - \obsolete - - Returns true if the last script evaluation resulted in an uncaught - exception; otherwise returns false. - - The exception state is cleared when evaluate() is called. - - \sa uncaughtException(), uncaughtExceptionLineNumber(), - uncaughtExceptionBacktrace() -*/ -bool QJSEngine::hasUncaughtException() const -{ - Q_D(const QJSEngine); - QScriptIsolate api(d); - return d->hasUncaughtException(); -} - -/*! - \obsolete - - Returns the current uncaught exception, or an invalid QJSValue - if there is no uncaught exception. - - The exception value is typically an \c{Error} object; in that case, - you can call toString() on the return value to obtain an error - message. - - \sa hasUncaughtException(), uncaughtExceptionLineNumber(), - uncaughtExceptionBacktrace() -*/ -QJSValue QJSEngine::uncaughtException() const -{ - Q_D(const QJSEngine); - QScriptIsolate api(d); - return d->scriptValueFromInternal(d->uncaughtException()); -} - -/*! - \obsolete - - Clears any uncaught exceptions in this engine. - - \sa hasUncaughtException() -*/ -void QJSEngine::clearExceptions() -{ - Q_D(QJSEngine); - QScriptIsolate api(d); - d->clearExceptions(); -} - -#endif // QT_DEPRECATED - -/*! - Runs the garbage collector. - - The garbage collector will attempt to reclaim memory by locating and disposing of objects that are - no longer reachable in the script environment. - - Normally you don't need to call this function; the garbage collector will automatically be invoked - when the QJSEngine decides that it's wise to do so (i.e. when a certain number of new objects - have been created). However, you can call this function to explicitly request that garbage - collection should be performed as soon as possible. - - \sa reportAdditionalMemoryCost() -*/ -void QJSEngine::collectGarbage() -{ - Q_D(QJSEngine); - QScriptIsolate api(d); - d->collectGarbage(); -} - -/*! - Evaluates \a program, using \a lineNumber as the base line number, - and returns the result of the evaluation. - - The script code will be evaluated in the current context. - - The evaluation of \a program can cause an exception in the - engine; in this case the return value will be the exception - that was thrown (typically an \c{Error} object). You can call - hasUncaughtException() to determine if an exception occurred in - the last call to evaluate(). - - \a lineNumber is used to specify a starting line number for \a - program; line number information reported by the engine that pertain - to this evaluation (e.g. uncaughtExceptionLineNumber()) will be - based on this argument. For example, if \a program consists of two - lines of code, and the statement on the second line causes a script - exception, uncaughtExceptionLineNumber() would return the given \a - lineNumber plus one. When no starting line number is specified, line - numbers will be 1-based. - - \a fileName is used for error reporting. For example in error objects - the file name is accessible through the "fileName" property if it's - provided with this function. -*/ -QJSValue QJSEngine::evaluate(const QString& program, const QString& fileName, int lineNumber) -{ - Q_D(QJSEngine); - QScriptIsolate api(d, QScriptIsolate::NotNullEngine); - v8::HandleScope handleScope; - return QJSValuePrivate::get(d->evaluate(program, fileName, lineNumber)); -} - -/*! - Creates a JavaScript object of class Object. - - The prototype of the created object will be the Object - prototype object. - - \sa newArray(), QJSValue::setProperty() -*/ -QJSValue QJSEngine::newObject() -{ - Q_D(QJSEngine); - QScriptIsolate api(d, QScriptIsolate::NotNullEngine); - v8::HandleScope handleScope; - return QJSValuePrivate::get(new QJSValuePrivate(d, v8::Object::New())); -} - -/*! - Creates a JavaScript object of class Array with the given \a length. - - \sa newObject() -*/ -QJSValue QJSEngine::newArray(uint length) -{ - Q_D(QJSEngine); - QScriptIsolate api(d, QScriptIsolate::NotNullEngine); - v8::HandleScope handleScope; - return QJSValuePrivate::get(d->newArray(length)); -} - -/*! - Creates a JavaScript object that wraps the given QObject \a - object, using JavaScriptOwnership. The given \a options control - various aspects of the interaction with the resulting script object. - - Signals and slots, properties and children of \a object are - available as properties of the created QJSValue. - - If \a object is a null pointer, this function returns a null value. - - If a default prototype has been registered for the \a object's class - (or its superclass, recursively), the prototype of the new script - object will be set to be that default prototype. - - If the given \a object is deleted outside of the engine's control, any - attempt to access the deleted QObject's members through the JavaScript - wrapper object (either by script code or C++) will result in a - script exception. - - \sa QJSValue::toQObject(), reportAdditionalMemoryCost() -*/ -QJSValue QJSEngine::newQObject(QObject *object) -{ - Q_D(QJSEngine); - QScriptIsolate api(d, QScriptIsolate::NotNullEngine); - v8::HandleScope handleScope; - return d->scriptValueFromInternal(d->newQObject(object, QV8Engine::JavaScriptOwnership)); -} - -/*! - Returns this engine's Global Object. - - By default, the Global Object contains the built-in objects that are - part of \l{ECMA-262}, such as Math, Date and String. Additionally, - you can set properties of the Global Object to make your own - extensions available to all script code. Non-local variables in - script code will be created as properties of the Global Object, as - well as local variables in global code. -*/ -QJSValue QJSEngine::globalObject() const -{ - Q_D(const QJSEngine); - QScriptIsolate api(d, QScriptIsolate::NotNullEngine); - v8::HandleScope handleScope; - return d->scriptValueFromInternal(d->global()); -} - -/*! - * \internal - * used by QJSEngine::toScriptValue - */ -QJSValue QJSEngine::create(int type, const void *ptr) -{ - Q_D(QJSEngine); - QScriptIsolate api(d, QScriptIsolate::NotNullEngine); - v8::HandleScope handleScope; - return d->scriptValueFromInternal(d->metaTypeToJS(type, ptr)); -} - -/*! - \internal - \since 4.5 - convert \a value to \a type, store the result in \a ptr -*/ -bool QJSEngine::convertV2(const QJSValue &value, int type, void *ptr) -{ - QJSValuePrivate *vp = QJSValuePrivate::get(value); - QV8Engine *engine = vp->engine(); - if (engine) { - QScriptIsolate api(engine, QScriptIsolate::NotNullEngine); - v8::HandleScope handleScope; - return engine->metaTypeFromJS(*vp, type, ptr); - } else { - switch (type) { - case QMetaType::Bool: - *reinterpret_cast<bool*>(ptr) = vp->toBool(); - return true; - case QMetaType::Int: - *reinterpret_cast<int*>(ptr) = vp->toInt32(); - return true; - case QMetaType::UInt: - *reinterpret_cast<uint*>(ptr) = vp->toUInt32(); - return true; - case QMetaType::LongLong: - *reinterpret_cast<qlonglong*>(ptr) = vp->toInteger(); - return true; - case QMetaType::ULongLong: - *reinterpret_cast<qulonglong*>(ptr) = vp->toInteger(); - return true; - case QMetaType::Double: - *reinterpret_cast<double*>(ptr) = vp->toNumber(); - return true; - case QMetaType::QString: - *reinterpret_cast<QString*>(ptr) = vp->toString(); - return true; - case QMetaType::Float: - *reinterpret_cast<float*>(ptr) = vp->toNumber(); - return true; - case QMetaType::Short: - *reinterpret_cast<short*>(ptr) = vp->toInt32(); - return true; - case QMetaType::UShort: - *reinterpret_cast<unsigned short*>(ptr) = vp->toUInt16(); - return true; - case QMetaType::Char: - *reinterpret_cast<char*>(ptr) = vp->toInt32(); - return true; - case QMetaType::UChar: - *reinterpret_cast<unsigned char*>(ptr) = vp->toUInt16(); - return true; - case QMetaType::QChar: - *reinterpret_cast<QChar*>(ptr) = vp->toUInt16(); - return true; - default: - return false; - } - } -} - -/*! \fn QJSValue QJSEngine::toScriptValue(const T &value) - - Creates a QJSValue with the given \a value. - - \sa fromScriptValue() -*/ - -/*! \fn T QJSEngine::fromScriptValue(const QJSValue &value) - - Returns the given \a value converted to the template type \c{T}. - - \sa toScriptValue() -*/ - -QT_END_NAMESPACE - -#include "moc_qjsengine.cpp" diff --git a/src/declarative/qml/v8/qjsengine.h b/src/declarative/qml/v8/qjsengine.h deleted file mode 100644 index 94c4dffde4..0000000000 --- a/src/declarative/qml/v8/qjsengine.h +++ /dev/null @@ -1,141 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtScript module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL-ONLY$ -** GNU Lesser General Public License Usage -** 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. -** -** If you have questions regarding the use of this file, please contact -** us via http://www.qt-project.org/. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QJSENGINE_H -#define QJSENGINE_H - -#include <QtCore/qmetatype.h> - -#include <QtCore/qvariant.h> -#include <QtCore/qsharedpointer.h> -#include <QtCore/qobject.h> -#include <QtDeclarative/qjsvalue.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - - -class QV8Engine; - -template <typename T> -inline T qjsvalue_cast(const QJSValue &); - -class QJSEnginePrivate; -class Q_DECLARATIVE_EXPORT QJSEngine - : public QObject -{ - Q_OBJECT -public: -#ifdef QT_DEPRECATED - enum ContextOwnership { - AdoptCurrentContext, - CreateNewContext - }; - QT_DEPRECATED explicit QJSEngine(ContextOwnership ownership); -#endif - - QJSEngine(); - explicit QJSEngine(QObject *parent); - virtual ~QJSEngine(); - - QJSValue globalObject() const; - - QJSValue evaluate(const QString &program, const QString &fileName = QString(), int lineNumber = 1); - - QJSValue newObject(); - QJSValue newArray(uint length = 0); - - QJSValue newQObject(QObject *object); - - template <typename T> - inline QJSValue toScriptValue(const T &value) - { - return create(qMetaTypeId<T>(), &value); - } - template <typename T> - inline T fromScriptValue(const QJSValue &value) - { - return qjsvalue_cast<T>(value); - } - - void collectGarbage(); - - QV8Engine *handle() const { return d; } - -#ifdef QT_DEPRECATED - QT_DEPRECATED bool hasUncaughtException() const; - QT_DEPRECATED QJSValue uncaughtException() const; - QT_DEPRECATED void clearExceptions(); -#endif - -Q_SIGNALS: - void signalHandlerException(const QJSValue &exception); - -private: - QJSValue create(int type, const void *ptr); - - static bool convertV2(const QJSValue &value, int type, void *ptr); - - friend inline bool qjsvalue_cast_helper(const QJSValue &, int, void *); - -protected: - QJSEngine(QJSEnginePrivate &dd, QObject *parent = 0); - -private: - QV8Engine *d; - Q_DISABLE_COPY(QJSEngine) - Q_DECLARE_PRIVATE(QJSEngine) - friend class QV8Engine; -}; - -inline bool qjsvalue_cast_helper(const QJSValue &value, int type, void *ptr) -{ - return QJSEngine::convertV2(value, type, ptr); -} - -template<typename T> -T qjsvalue_cast(const QJSValue &value) -{ - T t; - const int id = qMetaTypeId<T>(); - - if (qjsvalue_cast_helper(value, id, &t)) - return t; - else if (value.isVariant()) - return qvariant_cast<T>(value.toVariant()); - - return T(); -} - -template <> -inline QVariant qjsvalue_cast<QVariant>(const QJSValue &value) -{ - return value.toVariant(); -} - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QJSENGINE_H diff --git a/src/declarative/qml/v8/qjsengine_p.h b/src/declarative/qml/v8/qjsengine_p.h deleted file mode 100644 index ecd5f7cc86..0000000000 --- a/src/declarative/qml/v8/qjsengine_p.h +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtScript module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL-ONLY$ -** GNU Lesser General Public License Usage -** 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. -** -** If you have questions regarding the use of this file, please contact -** us via http://www.qt-project.org/. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QJSENGINE_P_H -#define QJSENGINE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/private/qobject_p.h> -#include "qjsengine.h" - - -QT_BEGIN_NAMESPACE - - -class QJSEnginePrivate : public QObjectPrivate -{ - Q_DECLARE_PUBLIC(QJSEngine) - -public: - static QJSEnginePrivate* get(QJSEngine*e) { return e->d_func(); } - - QJSEnginePrivate() {} -}; - -QT_END_NAMESPACE - -#endif // QJSENGINE_P_H diff --git a/src/declarative/qml/v8/qjsvalue.cpp b/src/declarative/qml/v8/qjsvalue.cpp deleted file mode 100644 index e0a925c3bb..0000000000 --- a/src/declarative/qml/v8/qjsvalue.cpp +++ /dev/null @@ -1,856 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtScript module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL-ONLY$ -** GNU Lesser General Public License Usage -** 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. -** -** If you have questions regarding the use of this file, please contact -** us via http://www.qt-project.org/. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qscriptisolate_p.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> - -/*! - \since 5.0 - \class QJSValue - - \brief The QJSValue class acts as a container for Qt/JavaScript data types. - - \ingroup qtjavascript - \mainclass - - QJSValue supports the types defined in the \l{ECMA-262} - standard: The primitive types, which are Undefined, Null, Boolean, - Number, and String; and the Object type. Additionally, built-in - support is provided for Qt/C++ types such as QVariant and QObject. - - For the object-based types (including Date and RegExp), use the - newT() functions in QJSEngine (e.g. QJSEngine::newObject()) - to create a QJSValue of the desired type. For the primitive types, - use one of the QJSValue constructor overloads. - - The methods named isT() (e.g. isBool(), isUndefined()) can be - used to test if a value is of a certain type. The methods named - toT() (e.g. toBool(), toString()) can be used to convert a - QJSValue to another type. You can also use the generic - QJSValue_cast() function. - - Object values have zero or more properties which are themselves - QJSValues. Use setProperty() to set a property of an object, and - call property() to retrieve the value of a property. - - \snippet doc/src/snippets/code/src_script_qjsvalue.cpp 0 - - If you want to iterate over the properties of a script object, use - the QJSValueIterator class. - - Object values have an internal \c{prototype} property, which can be - accessed with prototype() and setPrototype(). - - Function objects (objects for which isCallable()) returns true) can - be invoked by calling call(). Constructor functions can be used to - construct new objects by calling callAsConstructor(). - - Use equals() or strictlyEquals() to compare a QJSValue to another. - - Note that a QJSValue for which isObject() is true only carries a - reference to an actual object; copying the QJSValue will only - copy the object reference, not the object itself. If you want to - clone an object (i.e. copy an object's properties to another - object), you can do so with the help of a \c{for-in} statement in - script code, or QJSValueIterator in C++. - - \sa QJSEngine, QJSValueIterator -*/ - -/*! - \enum QJSValue::SpecialValue - - This enum is used to specify a single-valued type. - - \value UndefinedValue An undefined value. - - \value NullValue A null value. -*/ - -QT_BEGIN_NAMESPACE - -/*! - Constructs a new QJSValue with a boolean \a value. -*/ -QJSValue::QJSValue(bool value) - : d_ptr(new QJSValuePrivate(value)) -{ -} - -/*! - Constructs a new QJSValue with a number \a value. -*/ -QJSValue::QJSValue(int value) - : d_ptr(new QJSValuePrivate(value)) -{ -} - -/*! - Constructs a new QJSValue with a number \a value. -*/ -QJSValue::QJSValue(uint value) - : d_ptr(new QJSValuePrivate(value)) -{ -} - -/*! - Constructs a new QJSValue with a number \a value. -*/ -QJSValue::QJSValue(double value) - : d_ptr(new QJSValuePrivate(value)) -{ -} - -/*! - Constructs a new QJSValue with a string \a value. -*/ -QJSValue::QJSValue(const QString& value) - : d_ptr(new QJSValuePrivate(value)) -{ -} - -/*! - Constructs a new QJSValue with a special \a value. -*/ -QJSValue::QJSValue(SpecialValue value) - : d_ptr(new QJSValuePrivate(value)) -{ -} - -/*! - Constructs a new QJSValue with a string \a value. -*/ -QJSValue::QJSValue(const QLatin1String &value) - : d_ptr(new QJSValuePrivate(value)) -{ -} - -/*! - Constructs a new QJSValue with a string \a value. -*/ -#ifndef QT_NO_CAST_FROM_ASCII -QJSValue::QJSValue(const char *value) - : d_ptr(new QJSValuePrivate(QString::fromAscii(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 - true), then only a reference to the underlying object is copied into - the new script value (i.e., the object itself is not copied). -*/ -QJSValue::QJSValue(const QJSValue& other) - : d_ptr(other.d_ptr) -{ -} - -/*! - Destroys this QJSValue. -*/ -QJSValue::~QJSValue() -{ -} - -/*! - Returns true if this QJSValue is of the primitive type Boolean; - otherwise returns false. - - \sa toBool() -*/ -bool QJSValue::isBool() const -{ - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->isBool(); -} - -/*! - Returns true if this QJSValue is of the primitive type Number; - otherwise returns false. - - \sa toNumber() -*/ -bool QJSValue::isNumber() const -{ - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->isNumber(); -} - -/*! - Returns true if this QJSValue is of the primitive type Null; - otherwise returns false. -*/ -bool QJSValue::isNull() const -{ - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->isNull(); -} - -/*! - Returns true if this QJSValue is of the primitive type String; - otherwise returns false. - - \sa toString() -*/ -bool QJSValue::isString() const -{ - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->isString(); -} - -/*! - Returns true if this QJSValue is of the primitive type Undefined; - otherwise returns false. -*/ -bool QJSValue::isUndefined() const -{ - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->isUndefined(); -} - -/*! - Returns true if this QJSValue is an object of the Error class; - otherwise returns false. -*/ -bool QJSValue::isError() const -{ - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->isError(); -} - -/*! - Returns true if this QJSValue is an object of the Array class; - otherwise returns false. - - \sa QJSEngine::newArray() -*/ -bool QJSValue::isArray() const -{ - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->isArray(); - } - -/*! - Returns true if this QJSValue is of the Object type; otherwise - returns false. - - Note that function values, variant values, and QObject values are - objects, so this function returns true for such values. - - \sa QJSEngine::newObject() -*/ -bool QJSValue::isObject() const -{ - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->isObject(); -} - -/*! - Returns true if this QJSValue can be called a function, otherwise - returns false. - - \sa call() -*/ -bool QJSValue::isCallable() const -{ - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->isCallable(); -} - -/*! - Returns true if this QJSValue is a variant value; - otherwise returns false. - - \sa toVariant() -*/ -bool QJSValue::isVariant() const -{ - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->isVariant(); -} - -/*! - Returns the string value of this QJSValue, as defined in - \l{ECMA-262} section 9.8, "ToString". - - Note that if this QJSValue is an object, calling this function - has side effects on the script engine, since the engine will call - the object's toString() function (and possibly valueOf()) in an - attempt to convert the object to a primitive value (possibly - resulting in an uncaught script exception). - - \sa isString() -*/ -QString QJSValue::toString() const -{ - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->toString(); -} - -/*! - Returns the number value of this QJSValue, as defined in - \l{ECMA-262} section 9.3, "ToNumber". - - Note that if this QJSValue is an object, calling this function - has side effects on the script engine, since the engine will call - the object's valueOf() function (and possibly toString()) in an - attempt to convert the object to a primitive value (possibly - resulting in an uncaught script exception). - - \sa isNumber(), toInt(), toUInt() -*/ -double QJSValue::toNumber() const -{ - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->toNumber(); -} - -/*! - Returns the boolean value of this QJSValue, using the conversion - rules described in \l{ECMA-262} section 9.2, "ToBoolean". - - Note that if this QJSValue is an object, calling this function - has side effects on the script engine, since the engine will call - the object's valueOf() function (and possibly toString()) in an - attempt to convert the object to a primitive value (possibly - resulting in an uncaught script exception). - - \sa isBool() -*/ -bool QJSValue::toBool() const -{ - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->toBool(); -} - -/*! - Returns the signed 32-bit integer value of this QJSValue, using - the conversion rules described in \l{ECMA-262} section 9.5, "ToInt32". - - Note that if this QJSValue is an object, calling this function - has side effects on the script engine, since the engine will call - the object's valueOf() function (and possibly toString()) in an - attempt to convert the object to a primitive value (possibly - resulting in an uncaught script exception). - - \sa toNumber(), toUInt() -*/ -qint32 QJSValue::toInt() const -{ - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->toInt32(); -} - -/*! - Returns the unsigned 32-bit integer value of this QJSValue, using - the conversion rules described in \l{ECMA-262} section 9.6, "ToUint32". - - Note that if this QJSValue is an object, calling this function - has side effects on the script engine, since the engine will call - the object's valueOf() function (and possibly toString()) in an - attempt to convert the object to a primitive value (possibly - resulting in an uncaught script exception). - - \sa toNumber(), toInt() -*/ -quint32 QJSValue::toUInt() const -{ - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->toUInt32(); -} - -/*! - Returns the QVariant value of this QJSValue, if it can be - converted to a QVariant; otherwise returns an invalid QVariant. - The conversion is performed according to the following table: - - \table - \header \o Input Type \o Result - \row \o Undefined \o An invalid QVariant. - \row \o Null \o An invalid QVariant. - \row \o Boolean \o A QVariant containing the value of the boolean. - \row \o Number \o A QVariant containing the value of the number. - \row \o String \o A QVariant containing the value of the string. - \row \o QVariant Object \o The result is the QVariant value of the object (no conversion). - \row \o QObject Object \o A QVariant containing a pointer to the QObject. - \row \o Date Object \o A QVariant containing the date value (toDateTime()). - \row \o RegExp Object \o A QVariant containing the regular expression value. - \row \o Array Object \o The array is converted to a QVariantList. Each element is converted to a QVariant, recursively; cyclic references are not followed. - \row \o Object \o The object is converted to a QVariantMap. Each property is converted to a QVariant, recursively; cyclic references are not followed. - \endtable - - \sa isVariant() -*/ -QVariant QJSValue::toVariant() const -{ - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->toVariant(); -} - -/*! - Calls this QJSValue as a function, passing \a args as arguments - to the function, and using the globalObject() as the "this"-object. - Returns the value returned from the function. - - If this QJSValue is not callable, call() does nothing and - returns an undefined QJSValue. - - Calling call() can cause an exception to occur in the script engine; - in that case, call() returns the value that was thrown (typically an - \c{Error} object). You can call - QJSEngine::hasUncaughtException() to determine if an exception - occurred. - - \sa isCallable(), callWithInstance(), callAsConstructor() -*/ -QJSValue QJSValue::call(const QJSValueList &args) -{ - Q_D(QJSValue); - QScriptIsolate api(d->engine()); - return d->call(/*thisObject=*/0, args); -} - -/*! - Calls this QJSValue as a function, using \a instance as - the `this' object in the function call, and passing \a args - as arguments to the function. Returns the value returned from - the function. - - If this QJSValue is not a function, call() does nothing - and returns an undefined QJSValue. - - Note that if \a instance is not an object, the global object - (see \l{QJSEngine::globalObject()}) will be used as the - `this' object. - - Calling call() can cause an exception to occur in the script engine; - in that case, call() returns the value that was thrown (typically an - \c{Error} object). You can call - QJSEngine::hasUncaughtException() to determine if an exception - occurred. - - \sa call() -*/ -QJSValue QJSValue::callWithInstance(const QJSValue &instance, const QJSValueList &args) -{ - Q_D(QJSValue); - QScriptIsolate api(d->engine()); - return d->call(QJSValuePrivate::get(instance), args); -} - -/*! - Creates a new \c{Object} and calls this QJSValue as a - constructor, using the created object as the `this' object and - passing \a args as arguments. If the return value from the - constructor call is an object, then that object is returned; - otherwise the default constructed object is returned. - - If this QJSValue is not a function, callAsConstructor() does - nothing and returns an undefined QJSValue. - - Calling this function can cause an exception to occur in the - script engine; in that case, the value that was thrown - (typically an \c{Error} object) is returned. You can call - QJSEngine::hasUncaughtException() to determine if an exception - occurred. - - \sa call(), QJSEngine::newObject() -*/ -QJSValue QJSValue::callAsConstructor(const QJSValueList &args) -{ - Q_D(QJSValue); - QScriptIsolate api(d->engine()); - return QJSValuePrivate::get(d->callAsConstructor(args)); -} - -#ifdef QT_DEPRECATED - -/*! - \obsolete - - Returns the QJSEngine that created this QJSValue, - or 0 if this QJSValue is invalid or the value is not - associated with a particular engine. -*/ -QJSEngine* QJSValue::engine() const -{ - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - QV8Engine* engine = d->engine(); - if (engine) - return QV8Engine::get(engine); - return 0; -} - -#endif // QT_DEPRECATED - -/*! - If this QJSValue is an object, returns the internal prototype - (\c{__proto__} property) of this object; otherwise returns an - undefined QJSValue. - - \sa setPrototype(), isObject() -*/ -QJSValue QJSValue::prototype() const -{ - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return QJSValuePrivate::get(d->prototype()); -} - -/*! - If this QJSValue is an object, sets the internal prototype - (\c{__proto__} property) of this object to be \a prototype; - otherwise does nothing. - - The internal prototype should not be confused with the public - property with name "prototype"; the public prototype is usually - only set on functions that act as constructors. - - \sa prototype(), isObject() -*/ -void QJSValue::setPrototype(const QJSValue& prototype) -{ - Q_D(QJSValue); - QScriptIsolate api(d->engine()); - d->setPrototype(QJSValuePrivate::get(prototype)); -} - -/*! - Assigns the \a other value to this QJSValue. - - Note that if \a other is an object (isObject() returns true), - only a reference to the underlying object will be assigned; - the object itself will not be copied. -*/ -QJSValue& QJSValue::operator=(const QJSValue& other) -{ - d_ptr = other.d_ptr; - return *this; -} - -/*! - Returns true if this QJSValue is equal to \a other, otherwise - returns false. The comparison follows the behavior described in - \l{ECMA-262} section 11.9.3, "The Abstract Equality Comparison - Algorithm". - - This function can return true even if the type of this QJSValue - is different from the type of the \a other value; i.e. the - comparison is not strict. For example, comparing the number 9 to - the string "9" returns true; comparing an undefined value to a null - value returns true; comparing a \c{Number} object whose primitive - value is 6 to a \c{String} object whose primitive value is "6" - returns true; and comparing the number 1 to the boolean value - \c{true} returns true. If you want to perform a comparison - without such implicit value conversion, use strictlyEquals(). - - Note that if this QJSValue or the \a other value are objects, - calling this function has side effects on the script engine, since - the engine will call the object's valueOf() function (and possibly - toString()) in an attempt to convert the object to a primitive value - (possibly resulting in an uncaught script exception). - - \sa strictlyEquals() -*/ -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); -} - -/*! - Returns true if this QJSValue is equal to \a other using strict - comparison (no conversion), otherwise returns false. The comparison - follows the behavior described in \l{ECMA-262} section 11.9.6, "The - Strict Equality Comparison Algorithm". - - If the type of this QJSValue is different from the type of the - \a other value, this function returns false. If the types are equal, - the result depends on the type, as shown in the following table: - - \table - \header \o Type \o Result - \row \o Undefined \o true - \row \o Null \o true - \row \o Boolean \o true if both values are true, false otherwise - \row \o Number \o false if either value is NaN (Not-a-Number); true if values are equal, false otherwise - \row \o String \o true if both values are exactly the same sequence of characters, false otherwise - \row \o Object \o true if both values refer to the same object, false otherwise - \endtable - - \sa equals() -*/ -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); -} - -/*! - Returns the value of this QJSValue's property with the given \a name. - If no such property exists, an undefined QJSValue is returned. - - If the property is implemented using a getter function (i.e. has the - PropertyGetter flag set), calling property() has side-effects on the - script engine, since the getter function will be called (possibly - resulting in an uncaught script exception). If an exception - occurred, property() returns the value that was thrown (typically - an \c{Error} object). - - \sa setProperty(), hasProperty(), QJSValueIterator -*/ -QJSValue QJSValue::property(const QString& name) const -{ - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return QJSValuePrivate::get(d->property(name)); -} - -/*! - \overload - - Returns the property at the given \a arrayIndex. - - This function is provided for convenience and performance when - working with array objects. - - If this QJSValue is not an Array object, this function behaves - as if property() was called with the string representation of \a - arrayIndex. -*/ -QJSValue QJSValue::property(quint32 arrayIndex) const -{ - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return QJSValuePrivate::get(d->property(arrayIndex)); -} - -/*! - Sets the value of this QJSValue's property with the given \a name to - the given \a value. - - If this QJSValue is not an object, this function does nothing. - - If this QJSValue does not already have a property with name \a name, - a new property is created. - - \sa property(), deleteProperty() -*/ -void QJSValue::setProperty(const QString& name, const QJSValue& value) -{ - Q_D(QJSValue); - QScriptIsolate api(d->engine()); - d->setProperty(name, QJSValuePrivate::get(value)); -} - -/*! - \overload - - Sets the property at the given \a arrayIndex to the given \a value. - - This function is provided for convenience and performance when - working with array objects. - - If this QJSValue is not an Array object, this function behaves - as if setProperty() was called with the string representation of \a - arrayIndex. -*/ -void QJSValue::setProperty(quint32 arrayIndex, const QJSValue& value) -{ - Q_D(QJSValue); - QScriptIsolate api(d->engine()); - d->setProperty(arrayIndex, QJSValuePrivate::get(value)); -} - -/*! - Attempts to delete this object's property of the given \a name. - Returns true if the property was deleted, otherwise returns false. - - The behavior of this function is consistent with the JavaScript - delete operator. In particular: - - \list - \o Non-configurable properties cannot be deleted. - \o This function will return true even if this object doesn't - have a property of the given \a name (i.e., non-existent - properties are "trivially deletable"). - \o If this object doesn't have an own property of the given - \a name, but an object in the prototype() chain does, the - prototype object's property is not deleted, and this function - returns true. - \endlist - - \sa setProperty(), hasOwnProperty() -*/ -bool QJSValue::deleteProperty(const QString &name) -{ - Q_D(QJSValue); - QScriptIsolate api(d->engine()); - return d->deleteProperty(name); -} - -/*! - Returns true if this object has a property of the given \a name, - otherwise returns false. - - \sa property(), hasOwnProperty() -*/ -bool QJSValue::hasProperty(const QString &name) const -{ - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->hasProperty(name); -} - -/*! - Returns true if this object has an own (not prototype-inherited) - property of the given \a name, otherwise returns false. - - \sa property(), hasProperty() -*/ -bool QJSValue::hasOwnProperty(const QString &name) const -{ - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->hasOwnProperty(name); -} - -/*! - * If this QJSValue is a QObject, returns the QObject pointer - * that the QJSValue represents; otherwise, returns 0. - * - * If the QObject that this QJSValue wraps has been deleted, - * this function returns 0 (i.e. it is possible for toQObject() - * to return 0 even when isQObject() returns true). - * - * \sa isQObject() - */ -QObject *QJSValue::toQObject() const -{ - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->toQObject(); -} - -/*! - Returns a QDateTime representation of this value, in local time. - If this QJSValue is not a date, or the value of the date is NaN - (Not-a-Number), an invalid QDateTime is returned. - - \sa isDate() -*/ -QDateTime QJSValue::toDateTime() const -{ - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->toDataTime(); -} - -/*! - Returns true if this QJSValue is an object of the Date class; - otherwise returns false. - - \sa QJSEngine::newDate() -*/ -bool QJSValue::isDate() const -{ - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->isDate(); -} - -/*! - Returns true if this QJSValue is an object of the RegExp class; - otherwise returns false. -*/ -bool QJSValue::isRegExp() const -{ - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->isRegExp(); -} - -/*! - Returns true if this QJSValue is a QObject; otherwise returns - false. - - Note: This function returns true even if the QObject that this - QJSValue wraps has been deleted. - - \sa toQObject(), QJSEngine::newQObject() -*/ -bool QJSValue::isQObject() const -{ - Q_D(const QJSValue); - QScriptIsolate api(d->engine()); - return d->isQObject(); -} - -QT_END_NAMESPACE diff --git a/src/declarative/qml/v8/qjsvalue.h b/src/declarative/qml/v8/qjsvalue.h deleted file mode 100644 index bfe0ec0951..0000000000 --- a/src/declarative/qml/v8/qjsvalue.h +++ /dev/null @@ -1,142 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtScript module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL-ONLY$ -** GNU Lesser General Public License Usage -** 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. -** -** If you have questions regarding the use of this file, please contact -** us via http://www.qt-project.org/. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QJSVALUE_H -#define QJSVALUE_H - -#include <QtCore/qstring.h> - -#include <QtCore/qlist.h> -#include <QtCore/qsharedpointer.h> -#include <QtCore/qshareddata.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - - -class QJSValue; -class QJSEngine; -class QVariant; -class QObject; -struct QMetaObject; -class QDateTime; - -typedef QList<QJSValue> QJSValueList; - -class QJSValuePrivate; -struct QScriptValuePrivatePointerDeleter; -template <class T> class QScriptPassPointer; - -class Q_DECLARATIVE_EXPORT QJSValue -{ -public: - enum SpecialValue { - NullValue, - UndefinedValue - }; - -public: - QJSValue(SpecialValue value = UndefinedValue); - ~QJSValue(); - QJSValue(const QJSValue &other); - - QJSValue(bool value); - QJSValue(int value); - QJSValue(uint value); - QJSValue(double value); - QJSValue(const QString &value); - QJSValue(const QLatin1String &value); -#ifndef QT_NO_CAST_FROM_ASCII - QT_ASCII_CAST_WARN_CONSTRUCTOR QJSValue(const char *str); -#endif - - QJSValue &operator=(const QJSValue &other); - - bool isBool() const; - bool isNumber() const; - bool isNull() const; - bool isString() const; - bool isUndefined() const; - bool isVariant() const; - bool isQObject() const; - bool isObject() const; - bool isDate() const; - bool isRegExp() const; - bool isArray() const; - bool isError() const; - - QString toString() const; - double toNumber() const; - qint32 toInt() const; - quint32 toUInt() const; - bool toBool() const; - QVariant toVariant() const; - QObject *toQObject() const; - QDateTime toDateTime() const; - - bool equals(const QJSValue &other) const; - bool strictlyEquals(const QJSValue &other) const; - - QJSValue prototype() const; - void setPrototype(const QJSValue &prototype); - - QJSValue property(const QString &name) const; - void setProperty(const QString &name, const QJSValue &value); - - bool hasProperty(const QString &name) const; - bool hasOwnProperty(const QString &name) const; - - QJSValue property(quint32 arrayIndex) const; - void setProperty(quint32 arrayIndex, const QJSValue &value); - - bool deleteProperty(const QString &name); - - bool isCallable() const; - QJSValue call(const QJSValueList &args = QJSValueList()); - QJSValue callWithInstance(const QJSValue &instance, const QJSValueList &args = QJSValueList()); - QJSValue callAsConstructor(const QJSValueList &args = QJSValueList()); - -#ifdef QT_DEPRECATED - QT_DEPRECATED QJSEngine *engine() const; -#endif - -private: - // 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) -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif diff --git a/src/declarative/qml/v8/qjsvalue_impl_p.h b/src/declarative/qml/v8/qjsvalue_impl_p.h deleted file mode 100644 index cd33859c50..0000000000 --- a/src/declarative/qml/v8/qjsvalue_impl_p.h +++ /dev/null @@ -1,977 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtScript module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL-ONLY$ -** GNU Lesser General Public License Usage -** 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. -** -** If you have questions regarding the use of this file, please contact -** us via http://www.qt-project.org/. -** -** $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(); - m_engine->setException(tryCatch.Exception(), tryCatch.Message()); - } - 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(); - 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)->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 bool QJSValuePrivate::lessThan(QJSValuePrivate *other) const -{ - if (engine() != other->engine() && engine() && other->engine()) { - qWarning("QJSValue::lessThan: cannot compare to a value created in a different engine"); - return false; - } - - if (isString() && other->isString()) - return toString() < other->toString(); - - if (isObject() || other->isObject()) { - v8::HandleScope handleScope; - QV8Engine *eng = m_engine ? engine() : other->engine(); - // FIXME: lessThan can throw an exception which will be dropped by this code: - Q_ASSERT(eng); - eng->saveException(); - QScriptSharedDataPointer<QJSValuePrivate> cmp(eng->evaluate(QString::fromLatin1("(function(a,b){return a<b})"))); - Q_ASSERT(cmp->isFunction()); - v8::Handle<v8::Value> args[2]; - cmp->prepareArgumentsForCall(args, QJSValueList() << QJSValuePrivate::get(this) << QJSValuePrivate::get(other)); - QScriptSharedDataPointer<QJSValuePrivate> resultValue(cmp->call(0, 2, args)); - bool result = resultValue->toBool(); - eng->restoreException(); - return result; - } - - double nthis = toNumber(); - double nother = other->toNumber(); - if (qIsNaN(nthis) || qIsNaN(nother)) { - // Should return undefined in ECMA standard. - return false; - } - return nthis < nother; -} - -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)->Set(name, value->m_value, v8::PropertyAttribute(attribs & QJSConverter::PropertyAttributeMask)); -// } - if (tryCatch.HasCaught()) - engine()->setException(tryCatch.Exception(), tryCatch.Message()); -} - -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 dont 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::TryCatch tryCatch; - v8::Object::Cast(*m_value)->Set(index, value->m_value); - if (tryCatch.HasCaught()) - engine()->setException(tryCatch.Exception(), tryCatch.Message()); -} - -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)); - - v8::TryCatch tryCatch; - v8::Handle<v8::Value> result = self->Get(name); - if (tryCatch.HasCaught()) { - result = tryCatch.Exception(); - engine()->setException(result, tryCatch.Message()); - return new QJSValuePrivate(engine(), result); - } - 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())); - } 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)); - } - - if (argc < 0) { - v8::Local<v8::Value> exeption = v8::Exception::TypeError(v8::String::New("Arguments must be an array")); - e->setException(exeption); - return new QJSValuePrivate(e, exeption); - } - - v8::TryCatch tryCatch; - v8::Handle<v8::Value> result = v8::Object::Cast(*m_value)->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")); - e->setException(result, tryCatch.Message()); - } - - 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")); - e->setException(exeption); - return new QJSValuePrivate(e, exeption); - } - - v8::TryCatch tryCatch; - v8::Handle<v8::Value> result = v8::Object::Cast(*m_value)->CallAsConstructor(argc, argv); - - if (result.IsEmpty()) { - result = tryCatch.Exception(); - e->setException(result, tryCatch.Message()); - } - - 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); -} - -/*! - * 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/declarative/qml/v8/qjsvalue_p.h b/src/declarative/qml/v8/qjsvalue_p.h deleted file mode 100644 index 3eccba64bd..0000000000 --- a/src/declarative/qml/v8/qjsvalue_p.h +++ /dev/null @@ -1,195 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtScript module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL-ONLY$ -** GNU Lesser General Public License Usage -** 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. -** -** If you have questions regarding the use of this file, please contact -** us via http://www.qt-project.org/. -** -** $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_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" - -QT_BEGIN_NAMESPACE - -class QV8Engine; - -/*! - \internal - \class QJSValuePrivate -*/ -class QJSValuePrivate - : public QSharedData -{ -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 bool lessThan(QJSValuePrivate *other) const; - - 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> 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; -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(QJSValuePrivate::PropertyFlags) - -QT_END_NAMESPACE - -#endif diff --git a/src/declarative/qml/v8/qjsvalueiterator.cpp b/src/declarative/qml/v8/qjsvalueiterator.cpp deleted file mode 100644 index 4c3fa15fd3..0000000000 --- a/src/declarative/qml/v8/qjsvalueiterator.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtScript module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL-ONLY$ -** GNU Lesser General Public License Usage -** 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. -** -** If you have questions regarding the use of this file, please contact -** us via http://www.qt-project.org/. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#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 - -/*! - \class QJSValueIterator - - \brief The QJSValueIterator class provides a Java-style iterator for QJSValue. - - \ingroup qtjavascript - - - The QJSValueIterator constructor takes a QJSValue as - argument. After construction, the iterator is located at the very - beginning of the sequence of properties. Here's how to iterate over - all the properties of a QJSValue: - - \snippet doc/src/snippets/code/src_script_qjsvalueiterator.cpp 0 - - The next() advances the iterator. The name() and value() - functions return the name and value of the last item that was - jumped over. - - Note that QJSValueIterator only iterates over the QJSValue's - own properties; i.e. it does not follow the prototype chain. You can - use a loop like this to follow the prototype chain: - - \snippet doc/src/snippets/code/src_script_qjsvalueiterator.cpp 1 - - Note that QJSValueIterator will not automatically skip over - properties that have the QJSValue::SkipInEnumeration flag set; - that flag only affects iteration in script code. If you want, you - can skip over such properties with code like the following: - - \snippet doc/src/snippets/code/src_script_qjsvalueiterator.cpp 2 - - \sa QJSValue::property() -*/ - -/*! - Constructs an iterator for traversing \a object. The iterator is - set to be at the front of the sequence of properties (before the - first property). -*/ -QJSValueIterator::QJSValueIterator(const QJSValue& object) - : d_ptr(new QJSValueIteratorPrivate(QJSValuePrivate::get(object))) -{} - -/*! - Destroys the iterator. -*/ -QJSValueIterator::~QJSValueIterator() -{} - -/*! - Returns true if there is at least one item ahead of the iterator - (i.e. the iterator is \e not at the back of the property sequence); - otherwise returns false. - - \sa next() -*/ -bool QJSValueIterator::hasNext() const -{ - Q_D(const QJSValueIterator); - QScriptIsolate api(d->engine()); - return d->hasNext(); -} - -/*! - Advances the iterator by one position. - Returns true if there is at least one item ahead of the iterator - (i.e. the iterator is \e not at the back of the property sequence); - otherwise returns false. - - Calling this function on an iterator located at the back of the - container leads to undefined results. - - \sa hasNext(), name() -*/ -bool QJSValueIterator::next() -{ - Q_D(QJSValueIterator); - QScriptIsolate api(d->engine()); - return d->next(); -} - -/*! - Returns the name of the last property that was jumped over using - next(). - - \sa value() -*/ -QString QJSValueIterator::name() const -{ - Q_D(const QJSValueIterator); - QScriptIsolate api(d->engine()); - return d_ptr->name(); -} - - -/*! - Returns the value of the last property that was jumped over using - next(). - - \sa name() -*/ -QJSValue QJSValueIterator::value() const -{ - Q_D(const QJSValueIterator); - QScriptIsolate api(d->engine()); - return QJSValuePrivate::get(d->value()); -} - - -/*! - Makes the iterator operate on \a object. The iterator is set to be - at the front of the sequence of properties (before the first - property). -*/ -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/declarative/qml/v8/qjsvalueiterator.h b/src/declarative/qml/v8/qjsvalueiterator.h deleted file mode 100644 index 5f5446430e..0000000000 --- a/src/declarative/qml/v8/qjsvalueiterator.h +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtScript module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL-ONLY$ -** GNU Lesser General Public License Usage -** 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. -** -** If you have questions regarding the use of this file, please contact -** us via http://www.qt-project.org/. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSCRIPTVALUEITERATOR_H -#define QSCRIPTVALUEITERATOR_H - -#include <QtDeclarative/qjsvalue.h> -#include <QtCore/qscopedpointer.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - - -class QString; - -class QJSValueIteratorPrivate; -class Q_DECLARATIVE_EXPORT QJSValueIterator -{ -public: - QJSValueIterator(const QJSValue &value); - ~QJSValueIterator(); - - bool hasNext() const; - bool next(); - - QString name() const; - - QJSValue value() const; - QJSValueIterator& operator=(QJSValue &value); - -private: - QScopedPointer<QJSValueIteratorPrivate> d_ptr; - - Q_DECLARE_PRIVATE(QJSValueIterator) - Q_DISABLE_COPY(QJSValueIterator) -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QSCRIPTVALUEITERATOR_H diff --git a/src/declarative/qml/v8/qjsvalueiterator_impl_p.h b/src/declarative/qml/v8/qjsvalueiterator_impl_p.h deleted file mode 100644 index 40814b1969..0000000000 --- a/src/declarative/qml/v8/qjsvalueiterator_impl_p.h +++ /dev/null @@ -1,121 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL-ONLY$ -** GNU Lesser General Public License Usage -** 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. -** -** If you have questions regarding the use of this file, please contact -** us via http://www.qt-project.org/. -** -** $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" - -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; -} - -#endif // QJSVALUEITERATOR_IMPL_P_H diff --git a/src/declarative/qml/v8/qjsvalueiterator_p.h b/src/declarative/qml/v8/qjsvalueiterator_p.h deleted file mode 100644 index d1869506e9..0000000000 --- a/src/declarative/qml/v8/qjsvalueiterator_p.h +++ /dev/null @@ -1,68 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL-ONLY$ -** GNU Lesser General Public License Usage -** 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. -** -** If you have questions regarding the use of this file, please contact -** us via http://www.qt-project.org/. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QJSVALUEITERATOR_P_H -#define QJSVALUEITERATOR_P_H - -#include <private/qintrusivelist_p.h> -#include "qjsvalue_p.h" - -#include <private/qv8_p.h> - -QT_BEGIN_NAMESPACE - -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; -}; - - -QT_END_NAMESPACE - -#endif // QJSVALUEITERATOR_P_H diff --git a/src/declarative/qml/v8/qscript_impl_p.h b/src/declarative/qml/v8/qscript_impl_p.h deleted file mode 100644 index fdbf2f0097..0000000000 --- a/src/declarative/qml/v8/qscript_impl_p.h +++ /dev/null @@ -1,43 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtScript module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL-ONLY$ -** GNU Lesser General Public License Usage -** 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. -** -** If you have questions regarding the use of this file, please contact -** us via http://www.qt-project.org/. -** -** $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/declarative/qml/v8/qscriptisolate_p.h b/src/declarative/qml/v8/qscriptisolate_p.h deleted file mode 100644 index 4afa74756f..0000000000 --- a/src/declarative/qml/v8/qscriptisolate_p.h +++ /dev/null @@ -1,71 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtScript module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL-ONLY$ -** GNU Lesser General Public License Usage -** 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. -** -** If you have questions regarding the use of this file, please contact -** us via http://www.qt-project.org/. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef APIPREAMBLE_P_H -#define APIPREAMBLE_P_H - -#include <private/qv8_p.h> -#include "qv8engine_p.h" - -QT_BEGIN_NAMESPACE - -/** - \internal - Class used to switch to the right isolate. It does the same thing as v8::Isolate::Scope but - it checks for a null engine. - \attention We decided to put context switching "up" which means that it should be as high - as possible on call stack. And it should be switched at most once per public API function call. -*/ -class QScriptIsolate { -public: - // OperationMode was introduced to reduce number of checking for a null engine pointer. If we - // know that given pointer is not null than we should pass NotNullEngine as constructor argument - // that would nicely remove checking on compilation time. - enum OperationMode {Default, NotNullEngine}; - inline QScriptIsolate(const QV8Engine *engine, const OperationMode mode = Default) - : m_engine(engine) - , m_mode(mode) - { - if (m_mode == NotNullEngine || m_engine) { - Q_ASSERT(m_engine); - m_engine->context()->Enter(); - } - } - - inline ~QScriptIsolate() - { - if (m_mode == NotNullEngine || m_engine) { - m_engine->context()->Exit(); - } - } - -private: - Q_DISABLE_COPY(QScriptIsolate); - const QV8Engine *m_engine; - const OperationMode m_mode; -}; - - -QT_END_NAMESPACE - -#endif // APIPREAMBLE_P_H diff --git a/src/declarative/qml/v8/qscriptoriginalglobalobject_p.h b/src/declarative/qml/v8/qscriptoriginalglobalobject_p.h deleted file mode 100644 index 12321cc71a..0000000000 --- a/src/declarative/qml/v8/qscriptoriginalglobalobject_p.h +++ /dev/null @@ -1,159 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtScript module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL-ONLY$ -** GNU Lesser General Public License Usage -** 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. -** -** If you have questions regarding the use of this file, please contact -** us via http://www.qt-project.org/. -** -** $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/declarative/qml/v8/qscriptshareddata_p.h b/src/declarative/qml/v8/qscriptshareddata_p.h deleted file mode 100644 index df95b26206..0000000000 --- a/src/declarative/qml/v8/qscriptshareddata_p.h +++ /dev/null @@ -1,151 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtScript module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL-ONLY$ -** GNU Lesser General Public License Usage -** 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. -** -** If you have questions regarding the use of this file, please contact -** us via http://www.qt-project.org/. -** -** $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/declarative/qml/v8/qscripttools_p.h b/src/declarative/qml/v8/qscripttools_p.h deleted file mode 100644 index fcea205f61..0000000000 --- a/src/declarative/qml/v8/qscripttools_p.h +++ /dev/null @@ -1,68 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtScript module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL-ONLY$ -** GNU Lesser General Public License Usage -** 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. -** -** If you have questions regarding the use of this file, please contact -** us via http://www.qt-project.org/. -** -** $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/declarative/qml/v8/qv8_p.h b/src/declarative/qml/v8/qv8_p.h deleted file mode 100644 index 13867bdfc8..0000000000 --- a/src/declarative/qml/v8/qv8_p.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <private/v8.h> diff --git a/src/declarative/qml/v8/qv8bindings.cpp b/src/declarative/qml/v8/qv8bindings.cpp deleted file mode 100644 index 439ba1e1a4..0000000000 --- a/src/declarative/qml/v8/qv8bindings.cpp +++ /dev/null @@ -1,285 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qv8bindings_p.h" - -#include <private/qv8_p.h> -#include <private/qdeclarativebinding_p.h> -#include <private/qdeclarativecompiler_p.h> -#include <private/qdeclarativeproperty_p.h> -#include <private/qdeclarativebinding_p_p.h> -#include <private/qdeclarativeexpression_p.h> -#include <private/qobject_p.h> -#include <private/qdeclarativetrace_p.h> -#include <private/qdeclarativeprofilerservice_p.h> - -QT_BEGIN_NAMESPACE - -static QDeclarativeJavaScriptExpression::VTable QV8Bindings_Binding_jsvtable = { - QV8Bindings::Binding::expressionIdentifier, - QV8Bindings::Binding::expressionChanged -}; - -QV8Bindings::Binding::Binding() -: QDeclarativeJavaScriptExpression(&QV8Bindings_Binding_jsvtable), target(0), parent(0) -{ -} - -void QV8Bindings::Binding::setEnabled(bool e, QDeclarativePropertyPrivate::WriteFlags flags) -{ - if (enabledFlag() != e) { - setEnabledFlag(e); - - if (e) update(flags); - } -} - -void QV8Bindings::refresh() -{ - int count = functions()->Length(); - for (int ii = 0; ii < count; ++ii) - bindings[ii].refresh(); -} - -void QV8Bindings::Binding::refresh() -{ - update(); -} - -int QV8Bindings::Binding::propertyIndex() const -{ - return instruction->property.encodedIndex(); -} - -QObject *QV8Bindings::Binding::object() const -{ - return target; -} - -void QV8Bindings::Binding::update(QDeclarativePropertyPrivate::WriteFlags flags) -{ - if (!enabledFlag()) - return; - - QDeclarativeTrace trace("V8 Binding Update"); - trace.addDetail("URL", parent->url()); - trace.addDetail("Line", instruction->line); - trace.addDetail("Column", instruction->column); - - QDeclarativeBindingProfiler prof(parent->urlString(), instruction->line, instruction->column); - - QDeclarativeContextData *context = parent->context(); - if (!context || !context->isValid()) - return; - - if (!updatingFlag()) { - setUpdatingFlag(true); - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(context->engine); - - bool isUndefined = false; - - DeleteWatcher watcher(this); - ep->referenceScarceResources(); - - v8::HandleScope handle_scope; - v8::Context::Scope scope(ep->v8engine()->context()); - v8::Local<v8::Value> result = - evaluate(context, - v8::Handle<v8::Function>::Cast(parent->functions()->Get(instruction->value)), - &isUndefined); - - trace.event("writing V8 result"); - bool needsErrorData = false; - if (!watcher.wasDeleted() && !hasError()) { - typedef QDeclarativePropertyPrivate PP; - needsErrorData = !PP::writeBinding(target, instruction->property, context, this, result, - isUndefined, flags); - } - - if (!watcher.wasDeleted()) { - - if (needsErrorData) { - QUrl url = parent->url(); - if (url.isEmpty()) url = QUrl(QLatin1String("<Unknown File>")); - - delayedError()->error.setUrl(url); - delayedError()->error.setLine(instruction->line); - delayedError()->error.setColumn(-1); - } - - if (hasError()) { - if (!delayedError()->addError(ep)) ep->warning(delayedError()->error); - } else { - clearError(); - } - - setUpdatingFlag(false); - } - - ep->dereferenceScarceResources(); - - } else { - QDeclarativeProperty p = QDeclarativePropertyPrivate::restore(target, instruction->property, - context); - QDeclarativeBindingPrivate::printBindingLoopError(p); - } -} - -QString QV8Bindings::Binding::expressionIdentifier(QDeclarativeJavaScriptExpression *e) -{ - Binding *This = static_cast<Binding *>(e); - return This->parent->urlString() + QLatin1String(":") + - QString::number(This->instruction->line); -} - -void QV8Bindings::Binding::expressionChanged(QDeclarativeJavaScriptExpression *e) -{ - Binding *This = static_cast<Binding *>(e); - This->update(QDeclarativePropertyPrivate::DontRemoveBinding); -} - -void QV8Bindings::Binding::destroy() -{ - setEnabledFlag(false); - removeFromObject(); - clear(); - clearError(); - parent->release(); -} - -QV8Bindings::QV8Bindings(QDeclarativeCompiledData::V8Program *program, - int line, - QDeclarativeContextData *context) -: program(program), bindings(0), refCount(1) -{ - program->cdata->addref(); - - QV8Engine *engine = QDeclarativeEnginePrivate::getV8Engine(context->engine); - - if (program->bindings.IsEmpty()) { - v8::HandleScope handle_scope; - v8::Context::Scope scope(engine->context()); - - v8::Local<v8::Script> script; - bool compileFailed = false; - { - v8::TryCatch try_catch; - const QByteArray &source = program->program; - script = engine->qmlModeCompile(source.constData(), source.length(), - program->cdata->name, line); - if (try_catch.HasCaught()) { - // The binding was not compiled. There are some exceptional cases which the - // expression rewriter does not rewrite properly (e.g., \r-terminated lines - // are not rewritten correctly but this bug is demed out-of-scope to fix for - // performance reasons; see QTBUG-24064). - compileFailed = true; - QDeclarativeError error; - error.setDescription(QString(QLatin1String("Exception occurred during compilation of binding at line: %1")).arg(line)); - v8::Local<v8::Message> message = try_catch.Message(); - if (!message.IsEmpty()) - QDeclarativeExpressionPrivate::exceptionToError(message, error); - QDeclarativeEnginePrivate::get(engine->engine())->warning(error); - program->bindings = qPersistentNew(v8::Array::New()); - } - } - - if (!compileFailed) { - v8::Local<v8::Value> result = script->Run(engine->contextWrapper()->sharedContext()); - if (result->IsArray()) { - program->bindings = qPersistentNew(v8::Local<v8::Array>::Cast(result)); - program->program.clear(); // We don't need the source anymore - } - } - } - - int bindingsCount = functions()->Length(); - if (bindingsCount) bindings = new QV8Bindings::Binding[bindingsCount]; - - setContext(context); -} - -QV8Bindings::~QV8Bindings() -{ - program->cdata->release(); - program = 0; - - delete [] bindings; - bindings = 0; -} - -QDeclarativeAbstractBinding * -QV8Bindings::configBinding(QObject *target, QObject *scope, - const QDeclarativeInstruction::instr_assignBinding *i) -{ - if (!bindings) // initialization failed. - return 0; - - QV8Bindings::Binding *rv = bindings + i->value; - - rv->instruction = i; - rv->target = target; - rv->setScopeObject(scope); - rv->setUseSharedContext(true); - rv->setNotifyOnValueChanged(true); - rv->parent = this; - - addref(); // This is decremented in Binding::destroy() - - return rv; -} - -const QUrl &QV8Bindings::url() const -{ - return program->cdata->url; -} - -const QString &QV8Bindings::urlString() const -{ - return program->cdata->name; -} - -v8::Persistent<v8::Array> &QV8Bindings::functions() const -{ - return program->bindings; -} - - -QT_END_NAMESPACE diff --git a/src/declarative/qml/v8/qv8bindings_p.h b/src/declarative/qml/v8/qv8bindings_p.h deleted file mode 100644 index 14de2d1705..0000000000 --- a/src/declarative/qml/v8/qv8bindings_p.h +++ /dev/null @@ -1,148 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QV8BINDINGS_P_H -#define QV8BINDINGS_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <private/qdeclarativepropertycache_p.h> -#include <private/qdeclarativeinstruction_p.h> -#include <private/qdeclarativeexpression_p.h> -#include <private/qdeclarativecompiler_p.h> -#include <private/qdeclarativebinding_p.h> -#include <private/qflagpointer_p.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -class QDeclarativeCompiledData; - -class QV8BindingsPrivate; -class QV8Bindings : public QDeclarativeAbstractExpression -{ -public: - QV8Bindings(QDeclarativeCompiledData::V8Program *, - int line, - QDeclarativeContextData *context); - virtual ~QV8Bindings(); - - QDeclarativeAbstractBinding *configBinding(QObject *target, QObject *scope, - const QDeclarativeInstruction::instr_assignBinding *); - - // Inherited from QDeclarativeAbstractExpression - virtual void refresh(); - - struct Binding : public QDeclarativeJavaScriptExpression, - public QDeclarativeAbstractBinding { - Binding(); - - void update() { QDeclarativeAbstractBinding::update(); } - void refresh(); - - // "Inherited" from QDeclarativeJavaScriptExpression - static QString expressionIdentifier(QDeclarativeJavaScriptExpression *); - static void expressionChanged(QDeclarativeJavaScriptExpression *); - - // Inherited from QDeclarativeAbstractBinding - virtual void setEnabled(bool, QDeclarativePropertyPrivate::WriteFlags flags); - virtual void update(QDeclarativePropertyPrivate::WriteFlags flags); - virtual void destroy(); - virtual int propertyIndex() const; - virtual QObject *object() const; - - QObject *target; - QV8Bindings *parent; - - // To save memory, we store flags inside the instruction pointer. - // flag1: enabled - // flag2: updating - QFlagPointer<const QDeclarativeInstruction::instr_assignBinding> instruction; - - inline bool enabledFlag() const { return instruction.flag(); } - inline void setEnabledFlag(bool v) { instruction.setFlagValue(v); } - inline bool updatingFlag() const { return instruction.flag2(); } - inline void setUpdatingFlag(bool v) { instruction.setFlag2Value(v); } - }; - - inline void addref(); - inline void release(); - -private: - Q_DISABLE_COPY(QV8Bindings) - - const QUrl &url() const; - const QString &urlString() const; - v8::Persistent<v8::Array> &functions() const; - - QDeclarativeCompiledData::V8Program *program; - Binding *bindings; - int refCount; -}; - -void QV8Bindings::addref() -{ - ++refCount; -} - -void QV8Bindings::release() -{ - if (0 == --refCount) - delete this; -} - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QV8BINDINGS_P_H - - diff --git a/src/declarative/qml/v8/qv8contextwrapper.cpp b/src/declarative/qml/v8/qv8contextwrapper.cpp deleted file mode 100644 index 8b7fbe8941..0000000000 --- a/src/declarative/qml/v8/qv8contextwrapper.cpp +++ /dev/null @@ -1,455 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qv8contextwrapper_p.h" -#include "qv8engine_p.h" - -#include <private/qdeclarativeengine_p.h> -#include <private/qdeclarativecontext_p.h> - -QT_BEGIN_NAMESPACE - -static QString internal(QLatin1String("You've stumbled onto an internal implementation detail " - "that should never have been exposed.")); - -class QV8ContextResource : public QV8ObjectResource -{ - V8_RESOURCE_TYPE(ContextType); - -public: - QV8ContextResource(QV8Engine *engine, QDeclarativeContextData *context, QObject *scopeObject); - ~QV8ContextResource(); - - inline QDeclarativeContextData *getContext() const; - inline QObject *getScopeObject() const; - - quint32 isSharedContext:1; - quint32 hasSubContexts:1; - quint32 readOnly:1; - quint32 dummy:29; - - QObject *secondaryScope; - - // This is a pretty horrible hack, and an abuse of external strings. When we create a - // sub-context (a context created by a Qt.include() in an external javascript file), - // we pass a specially crafted SubContext external string as the v8::Script::Data() to - // the script, which contains a pointer to the context. We can then access the - // v8::Script::Data() later on to resolve names and URLs against the sub-context instead - // of the main outer context. - struct SubContext : public v8::String::ExternalStringResource { - SubContext(QDeclarativeContextData *context) : context(context) {} - QDeclarativeGuardedContextData context; - - virtual const uint16_t* data() const { return (const uint16_t *)internal.constData(); } - virtual size_t length() const { return internal.length(); } - }; - -private: - QDeclarativeGuardedContextData context; - QDeclarativeGuard<QObject> scopeObject; - -}; - -QV8ContextResource::QV8ContextResource(QV8Engine *engine, QDeclarativeContextData *context, QObject *scopeObject) -: QV8ObjectResource(engine), isSharedContext(false), hasSubContexts(false), readOnly(true), - secondaryScope(0), context(context), scopeObject(scopeObject) -{ -} - -QV8ContextResource::~QV8ContextResource() -{ - if (context && context->isJSContext) - context->destroy(); -} - -// Returns the scope object -QObject *QV8ContextResource::getScopeObject() const -{ - if (isSharedContext) - return QDeclarativeEnginePrivate::get(engine->engine())->sharedScope; - else - return scopeObject; -} - -// Returns the context, including resolving a subcontext -QDeclarativeContextData *QV8ContextResource::getContext() const -{ - if (isSharedContext) - return QDeclarativeEnginePrivate::get(engine->engine())->sharedContext; - - if (!hasSubContexts) - return context; - - v8::Local<v8::Value> callingdata = v8::Context::GetCallingScriptData(); - if (callingdata.IsEmpty() || !callingdata->IsString()) - return context; - - v8::Local<v8::String> callingstring = callingdata->ToString(); - Q_ASSERT(callingstring->IsExternal()); - Q_ASSERT(callingstring->GetExternalStringResource()); - - SubContext *sc = static_cast<SubContext *>(callingstring->GetExternalStringResource()); - return sc->context; -} - -QV8ContextWrapper::QV8ContextWrapper() -: m_engine(0) -{ -} - -QV8ContextWrapper::~QV8ContextWrapper() -{ -} - -void QV8ContextWrapper::destroy() -{ - qPersistentDispose(m_sharedContext); - qPersistentDispose(m_urlConstructor); - qPersistentDispose(m_constructor); -} - -void QV8ContextWrapper::init(QV8Engine *engine) -{ - m_engine = engine; - { - v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New(); - ft->InstanceTemplate()->SetHasExternalResource(true); - ft->InstanceTemplate()->SetFallbackPropertyHandler(Getter, Setter); - m_constructor = qPersistentNew<v8::Function>(ft->GetFunction()); - } - { - v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New(); - ft->InstanceTemplate()->SetHasExternalResource(true); - ft->InstanceTemplate()->SetFallbackPropertyHandler(NullGetter, NullSetter); - m_urlConstructor = qPersistentNew<v8::Function>(ft->GetFunction()); - } - { - v8::Local<v8::Object> sharedContext = m_constructor->NewInstance(); - QV8ContextResource *r = new QV8ContextResource(engine, 0, 0); - r->isSharedContext = true; - sharedContext->SetExternalResource(r); - m_sharedContext = qPersistentNew<v8::Object>(sharedContext); - } -} - -v8::Local<v8::Object> QV8ContextWrapper::qmlScope(QDeclarativeContextData *ctxt, QObject *scope) -{ - // XXX NewInstance() should be optimized - v8::Local<v8::Object> rv = m_constructor->NewInstance(); - QV8ContextResource *r = new QV8ContextResource(m_engine, ctxt, scope); - rv->SetExternalResource(r); - return rv; -} - -v8::Local<v8::Object> QV8ContextWrapper::urlScope(const QUrl &url) -{ - QDeclarativeContextData *context = new QDeclarativeContextData; - context->url = url; - context->isInternal = true; - context->isJSContext = true; - - // XXX NewInstance() should be optimized - v8::Local<v8::Object> rv = m_urlConstructor->NewInstance(); - QV8ContextResource *r = new QV8ContextResource(m_engine, context, 0); - rv->SetExternalResource(r); - return rv; -} - -void QV8ContextWrapper::setReadOnly(v8::Handle<v8::Object> qmlglobal, bool readOnly) -{ - QV8ContextResource *resource = v8_resource_cast<QV8ContextResource>(qmlglobal); - Q_ASSERT(resource); - resource->readOnly = readOnly; -} - -void QV8ContextWrapper::addSubContext(v8::Handle<v8::Object> qmlglobal, v8::Handle<v8::Script> script, - QDeclarativeContextData *ctxt) -{ - QV8ContextResource *resource = v8_resource_cast<QV8ContextResource>(qmlglobal); - Q_ASSERT(resource); - resource->hasSubContexts = true; - script->SetData(v8::String::NewExternal(new QV8ContextResource::SubContext(ctxt))); -} - -QObject *QV8ContextWrapper::setSecondaryScope(v8::Handle<v8::Object> ctxt, QObject *scope) -{ - QV8ContextResource *resource = v8_resource_cast<QV8ContextResource>(ctxt); - if (!resource) return 0; - - QObject *rv = resource->secondaryScope; - resource->secondaryScope = scope; - return rv; -} - -QDeclarativeContextData *QV8ContextWrapper::callingContext() -{ - v8::Local<v8::Object> qmlglobal = v8::Context::GetCallingQmlGlobal(); - if (qmlglobal.IsEmpty()) return 0; - - QV8ContextResource *r = v8_resource_cast<QV8ContextResource>(qmlglobal); - return r?r->getContext():0; -} - -QDeclarativeContextData *QV8ContextWrapper::context(v8::Handle<v8::Value> value) -{ - if (!value->IsObject()) - return 0; - - v8::Handle<v8::Object> qmlglobal = v8::Handle<v8::Object>::Cast(value); - QV8ContextResource *r = v8_resource_cast<QV8ContextResource>(qmlglobal); - return r?r->getContext():0; -} - -v8::Handle<v8::Value> QV8ContextWrapper::NullGetter(v8::Local<v8::String> property, - const v8::AccessorInfo &info) -{ - QV8ContextResource *resource = v8_resource_check<QV8ContextResource>(info.This()); - - QV8Engine *engine = resource->engine; - - QString error = QLatin1String("Can't find variable: ") + engine->toString(property); - v8::ThrowException(v8::Exception::ReferenceError(engine->toString(error))); - return v8::Undefined(); -} - -v8::Handle<v8::Value> QV8ContextWrapper::Getter(v8::Local<v8::String> property, - const v8::AccessorInfo &info) -{ - QV8ContextResource *resource = v8_resource_check<QV8ContextResource>(info.This()); - - // Its possible we could delay the calculation of the "actual" context (in the case - // of sub contexts) until it is definately needed. - QDeclarativeContextData *context = resource->getContext(); - QDeclarativeContextData *expressionContext = context; - - if (!context) - return v8::Undefined(); - - if (v8::Context::GetCallingQmlGlobal() != info.This()) - return v8::Handle<v8::Value>(); - - // Search type (attached property/enum/imported scripts) names - // Secondary scope object - // while (context) { - // Search context properties - // Search scope object - // Search context object - // context = context->parent - // } - - QV8Engine *engine = resource->engine; - - QObject *scopeObject = resource->getScopeObject(); - - QHashedV8String propertystring(property); - - if (context->imports && QV8Engine::startsWithUpper(property)) { - // Search for attached properties, enums and imported scripts - QDeclarativeTypeNameCache::Result r = context->imports->query(propertystring); - - if (r.isValid()) { - if (r.scriptIndex != -1) { - int index = r.scriptIndex; - if (index < context->importedScripts.count()) - return context->importedScripts.at(index); - else - return v8::Undefined(); - } else if (r.type) { - return engine->typeWrapper()->newObject(scopeObject, r.type); - } else if (r.importNamespace) { - return engine->typeWrapper()->newObject(scopeObject, context->imports, r.importNamespace); - } - Q_ASSERT(!"Unreachable"); - } - - // Fall through - } - - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine->engine()); - QV8QObjectWrapper *qobjectWrapper = engine->qobjectWrapper(); - - if (resource->secondaryScope) { - v8::Handle<v8::Value> result = qobjectWrapper->getProperty(resource->secondaryScope, propertystring, - QV8QObjectWrapper::IgnoreRevision); - if (!result.IsEmpty()) return result; - } - - while (context) { - // Search context properties - if (context->propertyNames) { - int propertyIdx = context->propertyNames->value(propertystring); - - if (propertyIdx != -1) { - - if (propertyIdx < context->idValueCount) { - - ep->captureProperty(&context->idValues[propertyIdx].bindings); - return engine->newQObject(context->idValues[propertyIdx]); - } else { - - QDeclarativeContextPrivate *cp = context->asQDeclarativeContextPrivate(); - - ep->captureProperty(context->asQDeclarativeContext(), -1, - propertyIdx + cp->notifyIndex); - - const QVariant &value = cp->propertyValues.at(propertyIdx); - if (value.userType() == qMetaTypeId<QList<QObject*> >()) { - QDeclarativeListProperty<QObject> prop(context->asQDeclarativeContext(), (void*)propertyIdx, - 0, - QDeclarativeContextPrivate::context_count, - QDeclarativeContextPrivate::context_at); - return engine->listWrapper()->newList(prop, qMetaTypeId<QDeclarativeListProperty<QObject> >()); - } else { - return engine->fromVariant(cp->propertyValues.at(propertyIdx)); - } - } - } - } - - // Search scope object - if (scopeObject) { - v8::Handle<v8::Value> result = qobjectWrapper->getProperty(scopeObject, propertystring, - QV8QObjectWrapper::CheckRevision); - if (!result.IsEmpty()) return result; - } - scopeObject = 0; - - - // Search context object - if (context->contextObject) { - v8::Handle<v8::Value> result = qobjectWrapper->getProperty(context->contextObject, propertystring, - QV8QObjectWrapper::CheckRevision); - if (!result.IsEmpty()) return result; - } - - context = context->parent; - } - - expressionContext->unresolvedNames = true; - - QString error = QLatin1String("Can't find variable: ") + engine->toString(property); - v8::ThrowException(v8::Exception::ReferenceError(engine->toString(error))); - return v8::Undefined(); -} - -v8::Handle<v8::Value> QV8ContextWrapper::NullSetter(v8::Local<v8::String> property, - v8::Local<v8::Value>, - const v8::AccessorInfo &info) -{ - QV8ContextResource *resource = v8_resource_check<QV8ContextResource>(info.This()); - - QV8Engine *engine = resource->engine; - - if (!resource->readOnly) { - return v8::Handle<v8::Value>(); - } else { - QString error = QLatin1String("Invalid write to global property \"") + engine->toString(property) + - QLatin1String("\""); - v8::ThrowException(v8::Exception::Error(engine->toString(error))); - return v8::Handle<v8::Value>(); - } -} - -v8::Handle<v8::Value> QV8ContextWrapper::Setter(v8::Local<v8::String> property, - v8::Local<v8::Value> value, - const v8::AccessorInfo &info) -{ - QV8ContextResource *resource = v8_resource_check<QV8ContextResource>(info.This()); - - // Its possible we could delay the calculation of the "actual" context (in the case - // of sub contexts) until it is definately needed. - QDeclarativeContextData *context = resource->getContext(); - QDeclarativeContextData *expressionContext = context; - - if (!context) - return v8::Undefined(); - - if (v8::Context::GetCallingQmlGlobal() != info.This()) - return v8::Handle<v8::Value>(); - - // See QV8ContextWrapper::Getter for resolution order - - QV8Engine *engine = resource->engine; - QObject *scopeObject = resource->getScopeObject(); - - QHashedV8String propertystring(property); - - QV8QObjectWrapper *qobjectWrapper = engine->qobjectWrapper(); - - // Search scope object - if (resource->secondaryScope && - qobjectWrapper->setProperty(resource->secondaryScope, propertystring, value, - QV8QObjectWrapper::IgnoreRevision)) - return value; - - while (context) { - // Search context properties - if (context->propertyNames && -1 != context->propertyNames->value(propertystring)) - return value; - - // Search scope object - if (scopeObject && - qobjectWrapper->setProperty(scopeObject, propertystring, value, QV8QObjectWrapper::CheckRevision)) - return value; - scopeObject = 0; - - // Search context object - if (context->contextObject && - qobjectWrapper->setProperty(context->contextObject, propertystring, value, - QV8QObjectWrapper::CheckRevision)) - return value; - - context = context->parent; - } - - expressionContext->unresolvedNames = true; - - if (!resource->readOnly) { - return v8::Handle<v8::Value>(); - } else { - QString error = QLatin1String("Invalid write to global property \"") + engine->toString(property) + - QLatin1String("\""); - v8::ThrowException(v8::Exception::Error(engine->toString(error))); - return v8::Undefined(); - } -} - -QT_END_NAMESPACE diff --git a/src/declarative/qml/v8/qv8contextwrapper_p.h b/src/declarative/qml/v8/qv8contextwrapper_p.h deleted file mode 100644 index eabbc15f15..0000000000 --- a/src/declarative/qml/v8/qv8contextwrapper_p.h +++ /dev/null @@ -1,120 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QV8CONTEXTWRAPPER_P_H -#define QV8CONTEXTWRAPPER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/qglobal.h> -#include <private/qv8_p.h> - -QT_BEGIN_NAMESPACE - -class QUrl; -class QObject; -class QV8Engine; -class QDeclarativeContextData; -class QV8ContextWrapper -{ -public: - QV8ContextWrapper(); - ~QV8ContextWrapper(); - - void init(QV8Engine *); - void destroy(); - - v8::Local<v8::Object> qmlScope(QDeclarativeContextData *ctxt, QObject *scope); - v8::Local<v8::Object> urlScope(const QUrl &); - - void setReadOnly(v8::Handle<v8::Object>, bool); - - void addSubContext(v8::Handle<v8::Object> qmlglobal, v8::Handle<v8::Script>, - QDeclarativeContextData *ctxt); - - // XXX We only use the secondary scope to pass the "arguments" of the signal to - // on<SignalName> properties. Instead of doing this we should rewrite the - // JavaScript closure function to accept these arguments as named parameters. - // To keep backwards compatibility we have to check that the argument names are - // not members of the QV8Engine::illegalNames() set. - QObject *setSecondaryScope(v8::Handle<v8::Object>, QObject *); - - QDeclarativeContextData *callingContext(); - QDeclarativeContextData *context(v8::Handle<v8::Value>); - - inline v8::Handle<v8::Object> sharedContext() const; - -private: - static v8::Handle<v8::Value> NullGetter(v8::Local<v8::String> property, - const v8::AccessorInfo &info); - static v8::Handle<v8::Value> NullSetter(v8::Local<v8::String> property, - v8::Local<v8::Value> value, - const v8::AccessorInfo &info); - static v8::Handle<v8::Value> Getter(v8::Local<v8::String> property, - const v8::AccessorInfo &info); - static v8::Handle<v8::Value> Setter(v8::Local<v8::String> property, - v8::Local<v8::Value> value, - const v8::AccessorInfo &info); - - QV8Engine *m_engine; - v8::Persistent<v8::Function> m_constructor; - v8::Persistent<v8::Function> m_urlConstructor; - v8::Persistent<v8::Object> m_sharedContext; -}; - -v8::Handle<v8::Object> QV8ContextWrapper::sharedContext() const -{ - return m_sharedContext; -} - -QT_END_NAMESPACE - -#endif // QV8CONTEXTWRAPPER_P_H - diff --git a/src/declarative/qml/v8/qv8debug_p.h b/src/declarative/qml/v8/qv8debug_p.h deleted file mode 100644 index cf1d945712..0000000000 --- a/src/declarative/qml/v8/qv8debug_p.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <private/v8-debug.h> diff --git a/src/declarative/qml/v8/qv8domerrors.cpp b/src/declarative/qml/v8/qv8domerrors.cpp deleted file mode 100644 index 2f340e736f..0000000000 --- a/src/declarative/qml/v8/qv8domerrors.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qv8domerrors_p.h" -#include "qv8engine_p.h" - -QT_BEGIN_NAMESPACE - -void qt_add_domexceptions(QV8Engine *engine) -{ - // DOM Exception - v8::PropertyAttribute attributes = (v8::PropertyAttribute)(v8::ReadOnly | v8::DontEnum | v8::DontDelete); - - v8::Local<v8::Object> domexception = v8::Object::New(); - domexception->Set(v8::String::New("INDEX_SIZE_ERR"), v8::Integer::New(DOMEXCEPTION_INDEX_SIZE_ERR), attributes); - domexception->Set(v8::String::New("DOMSTRING_SIZE_ERR"), v8::Integer::New(DOMEXCEPTION_DOMSTRING_SIZE_ERR), attributes); - domexception->Set(v8::String::New("HIERARCHY_REQUEST_ERR"), v8::Integer::New(DOMEXCEPTION_HIERARCHY_REQUEST_ERR), attributes); - domexception->Set(v8::String::New("WRONG_DOCUMENT_ERR"), v8::Integer::New(DOMEXCEPTION_WRONG_DOCUMENT_ERR), attributes); - domexception->Set(v8::String::New("INVALID_CHARACTER_ERR"), v8::Integer::New(DOMEXCEPTION_INVALID_CHARACTER_ERR), attributes); - domexception->Set(v8::String::New("NO_DATA_ALLOWED_ERR"), v8::Integer::New(DOMEXCEPTION_NO_DATA_ALLOWED_ERR), attributes); - domexception->Set(v8::String::New("NO_MODIFICATION_ALLOWED_ERR"), v8::Integer::New(DOMEXCEPTION_NO_MODIFICATION_ALLOWED_ERR), attributes); - domexception->Set(v8::String::New("NOT_FOUND_ERR"), v8::Integer::New(DOMEXCEPTION_NOT_FOUND_ERR), attributes); - domexception->Set(v8::String::New("NOT_SUPPORTED_ERR"), v8::Integer::New(DOMEXCEPTION_NOT_SUPPORTED_ERR), attributes); - domexception->Set(v8::String::New("INUSE_ATTRIBUTE_ERR"), v8::Integer::New(DOMEXCEPTION_INUSE_ATTRIBUTE_ERR), attributes); - domexception->Set(v8::String::New("INVALID_STATE_ERR"), v8::Integer::New(DOMEXCEPTION_INVALID_STATE_ERR), attributes); - domexception->Set(v8::String::New("SYNTAX_ERR"), v8::Integer::New(DOMEXCEPTION_SYNTAX_ERR), attributes); - domexception->Set(v8::String::New("INVALID_MODIFICATION_ERR"), v8::Integer::New(DOMEXCEPTION_INVALID_MODIFICATION_ERR), attributes); - domexception->Set(v8::String::New("NAMESPACE_ERR"), v8::Integer::New(DOMEXCEPTION_NAMESPACE_ERR), attributes); - domexception->Set(v8::String::New("INVALID_ACCESS_ERR"), v8::Integer::New(DOMEXCEPTION_INVALID_ACCESS_ERR), attributes); - domexception->Set(v8::String::New("VALIDATION_ERR"), v8::Integer::New(DOMEXCEPTION_VALIDATION_ERR), attributes); - domexception->Set(v8::String::New("TYPE_MISMATCH_ERR"), v8::Integer::New(DOMEXCEPTION_TYPE_MISMATCH_ERR), attributes); - engine->global()->Set(v8::String::New("DOMException"), domexception); -} - -QT_END_NAMESPACE diff --git a/src/declarative/qml/v8/qv8domerrors_p.h b/src/declarative/qml/v8/qv8domerrors_p.h deleted file mode 100644 index 5131f960f1..0000000000 --- a/src/declarative/qml/v8/qv8domerrors_p.h +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QV8DOMERRORS_P_H -#define QV8DOMERRORS_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/qglobal.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE -// From DOM-Level-3-Core spec -// http://www.w3.org/TR/DOM-Level-3-Core/core.html -#define DOMEXCEPTION_INDEX_SIZE_ERR 1 -#define DOMEXCEPTION_DOMSTRING_SIZE_ERR 2 -#define DOMEXCEPTION_HIERARCHY_REQUEST_ERR 3 -#define DOMEXCEPTION_WRONG_DOCUMENT_ERR 4 -#define DOMEXCEPTION_INVALID_CHARACTER_ERR 5 -#define DOMEXCEPTION_NO_DATA_ALLOWED_ERR 6 -#define DOMEXCEPTION_NO_MODIFICATION_ALLOWED_ERR 7 -#define DOMEXCEPTION_NOT_FOUND_ERR 8 -#define DOMEXCEPTION_NOT_SUPPORTED_ERR 9 -#define DOMEXCEPTION_INUSE_ATTRIBUTE_ERR 10 -#define DOMEXCEPTION_INVALID_STATE_ERR 11 -#define DOMEXCEPTION_SYNTAX_ERR 12 -#define DOMEXCEPTION_INVALID_MODIFICATION_ERR 13 -#define DOMEXCEPTION_NAMESPACE_ERR 14 -#define DOMEXCEPTION_INVALID_ACCESS_ERR 15 -#define DOMEXCEPTION_VALIDATION_ERR 16 -#define DOMEXCEPTION_TYPE_MISMATCH_ERR 17 - -#define V8THROW_DOM(error, string) { \ - v8::Local<v8::Value> v = v8::Exception::Error(v8::String::New(string)); \ - v->ToObject()->Set(v8::String::New("code"), v8::Integer::New(error)); \ - v8::ThrowException(v); \ - return v8::Handle<v8::Value>(); \ -} -class QV8Engine; -void qt_add_domexceptions(QV8Engine *engine); - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QV8DOMERRORS_P_H diff --git a/src/declarative/qml/v8/qv8engine.cpp b/src/declarative/qml/v8/qv8engine.cpp deleted file mode 100644 index 04589fe244..0000000000 --- a/src/declarative/qml/v8/qv8engine.cpp +++ /dev/null @@ -1,1598 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qv8engine_p.h" - -#include <QtGui/QGuiApplication> - -#include "qv8contextwrapper_p.h" -#include "qv8valuetypewrapper_p.h" -#include "qv8sequencewrapper_p.h" -#include "qv8include_p.h" -#include "qjsengine_p.h" -#include "../../../3rdparty/javascriptcore/DateMath.h" - -#include <private/qdeclarativebuiltinfunctions_p.h> -#include <private/qdeclarativelist_p.h> -#include <private/qdeclarativeengine_p.h> -#include <private/qdeclarativeapplication_p.h> -#include <private/qdeclarativexmlhttprequest_p.h> -#include <private/qdeclarativelocale_p.h> - -#include "qscript_impl_p.h" -#include "qv8domerrors_p.h" -#include "qv8sqlerrors_p.h" - - -Q_DECLARE_METATYPE(QJSValue) -Q_DECLARE_METATYPE(QList<int>) - - -// XXX TODO: Need to check all the global functions will also work in a worker script where the -// QDeclarativeEngine is not available -QT_BEGIN_NAMESPACE - -static bool ObjectComparisonCallback(v8::Local<v8::Object> lhs, v8::Local<v8::Object> rhs) -{ - if (lhs == rhs) - return true; - - QV8ObjectResource *lhsr = static_cast<QV8ObjectResource*>(lhs->GetExternalResource()); - QV8ObjectResource *rhsr = static_cast<QV8ObjectResource*>(rhs->GetExternalResource()); - - Q_ASSERT(lhsr->engine == rhsr->engine); - - if (lhsr && rhsr) { - QV8ObjectResource::ResourceType lhst = lhsr->resourceType(); - QV8ObjectResource::ResourceType rhst = rhsr->resourceType(); - - switch (lhst) { - case QV8ObjectResource::ValueTypeType: - // a value type might be equal to a variant or another value type - if (rhst == QV8ObjectResource::ValueTypeType) { - return lhsr->engine->valueTypeWrapper()->isEqual(lhsr, lhsr->engine->valueTypeWrapper()->toVariant(rhsr)); - } else if (rhst == QV8ObjectResource::VariantType) { - return lhsr->engine->valueTypeWrapper()->isEqual(lhsr, lhsr->engine->variantWrapper()->toVariant(rhsr)); - } - break; - case QV8ObjectResource::VariantType: - // a variant might be equal to a value type or other variant. - if (rhst == QV8ObjectResource::VariantType) { - return lhsr->engine->variantWrapper()->toVariant(lhsr) == - lhsr->engine->variantWrapper()->toVariant(rhsr); - } else if (rhst == QV8ObjectResource::ValueTypeType) { - return rhsr->engine->valueTypeWrapper()->isEqual(rhsr, rhsr->engine->variantWrapper()->toVariant(lhsr)); - } - break; - case QV8ObjectResource::SequenceType: - // a sequence might be equal to itself. - if (rhst == QV8ObjectResource::SequenceType) { - return lhsr->engine->sequenceWrapper()->isEqual(lhsr, rhsr); - } - break; - default: - break; - } - } - - return false; -} - - -QV8Engine::QV8Engine(QJSEngine* qq, QJSEngine::ContextOwnership ownership) - : q(qq) - , m_engine(0) - , m_ownsV8Context(ownership == QJSEngine::CreateNewContext) - , m_xmlHttpRequestData(0) - , m_listModelData(0) -{ - qMetaTypeId<QJSValue>(); - qMetaTypeId<QList<int> >(); - - QByteArray v8args = qgetenv("V8ARGS"); - // change default v8 behaviour to not relocate breakpoints across lines - if (!v8args.contains("breakpoint_relocation")) - v8args.append(" --nobreakpoint_relocation"); - v8::V8::SetFlagsFromString(v8args.constData(), v8args.length()); - - ensurePerThreadIsolate(); - - v8::HandleScope handle_scope; - m_context = (ownership == QJSEngine::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); - - v8::V8::SetUserObjectComparisonCallbackFunction(ObjectComparisonCallback); - QV8GCCallback::registerGcPrologueCallback(); - m_strongReferencer = qPersistentNew(v8::Object::New()); - - m_stringWrapper.init(); - m_contextWrapper.init(this); - m_qobjectWrapper.init(this); - m_typeWrapper.init(this); - m_listWrapper.init(this); - m_variantWrapper.init(this); - m_valueTypeWrapper.init(this); - m_sequenceWrapper.init(this); - - { - v8::Handle<v8::Value> v = global()->Get(v8::String::New("Object"))->ToObject()->Get(v8::String::New("getOwnPropertyNames")); - m_getOwnPropertyNames = qPersistentNew<v8::Function>(v8::Handle<v8::Function>::Cast(v)); - } -} - -QV8Engine::~QV8Engine() -{ - Q_ASSERT_X(v8::Isolate::GetCurrent(), "QV8Engine::~QV8Engine()", "called after v8::Isolate has exited"); - for (int ii = 0; ii < m_extensionData.count(); ++ii) - delete m_extensionData[ii]; - m_extensionData.clear(); - - qt_rem_qmlxmlhttprequest(this, m_xmlHttpRequestData); - m_xmlHttpRequestData = 0; - delete m_listModelData; - m_listModelData = 0; - - qPersistentDispose(m_freezeObject); - qPersistentDispose(m_getOwnPropertyNames); - - invalidateAllValues(); - clearExceptions(); - - qPersistentDispose(m_strongReferencer); - - m_sequenceWrapper.destroy(); - m_valueTypeWrapper.destroy(); - m_variantWrapper.destroy(); - m_listWrapper.destroy(); - m_typeWrapper.destroy(); - m_qobjectWrapper.destroy(); - m_contextWrapper.destroy(); - m_stringWrapper.destroy(); - - m_originalGlobalObject.destroy(); - - if (m_ownsV8Context) - qPersistentDispose(m_context); -} - -QString QV8Engine::toStringStatic(v8::Handle<v8::Value> jsstr) -{ - return toStringStatic(jsstr->ToString()); -} - -QString QV8Engine::toStringStatic(v8::Handle<v8::String> jsstr) -{ - QString qstr; - qstr.resize(jsstr->Length()); - jsstr->Write((uint16_t*)qstr.data()); - return qstr; -} - -QVariant QV8Engine::toVariant(v8::Handle<v8::Value> value, int typeHint) -{ - if (value.IsEmpty()) - return QVariant(); - - if (typeHint == QVariant::Bool) - return QVariant(value->BooleanValue()); - - if (value->IsObject()) { - QV8ObjectResource *r = (QV8ObjectResource *)value->ToObject()->GetExternalResource(); - if (r) { - switch (r->resourceType()) { - case QV8ObjectResource::Context2DStyleType: - case QV8ObjectResource::Context2DPixelArrayType: - case QV8ObjectResource::SignalHandlerType: - case QV8ObjectResource::IncubatorType: - case QV8ObjectResource::VisualDataItemType: - case QV8ObjectResource::ContextType: - case QV8ObjectResource::XMLHttpRequestType: - case QV8ObjectResource::DOMNodeType: - case QV8ObjectResource::SQLDatabaseType: - case QV8ObjectResource::ListModelType: - case QV8ObjectResource::Context2DType: - case QV8ObjectResource::ParticleDataType: - case QV8ObjectResource::LocaleDataType: - return QVariant(); - case QV8ObjectResource::TypeType: - return m_typeWrapper.toVariant(r); - case QV8ObjectResource::QObjectType: - return qVariantFromValue<QObject *>(m_qobjectWrapper.toQObject(r)); - case QV8ObjectResource::ListType: - return m_listWrapper.toVariant(r); - case QV8ObjectResource::VariantType: - return m_variantWrapper.toVariant(r); - case QV8ObjectResource::ValueTypeType: - return m_valueTypeWrapper.toVariant(r); - case QV8ObjectResource::SequenceType: - return m_sequenceWrapper.toVariant(r); - } - } - } - - if (value->IsArray()) { - v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(value); - if (typeHint == qMetaTypeId<QList<QObject *> >()) { - QList<QObject *> list; - uint32_t length = array->Length(); - for (uint32_t ii = 0; ii < length; ++ii) { - v8::Local<v8::Value> arrayItem = array->Get(ii); - if (arrayItem->IsObject()) { - list << toQObject(arrayItem->ToObject()); - } else { - list << 0; - } - } - - return qVariantFromValue<QList<QObject*> >(list); - } - - bool succeeded = false; - QVariant retn = m_sequenceWrapper.toVariant(array, typeHint, &succeeded); - if (succeeded) - return retn; - } - - return toBasicVariant(value); -} - -static v8::Handle<v8::Array> arrayFromStringList(QV8Engine *engine, const QStringList &list) -{ - v8::Context::Scope scope(engine->context()); - v8::Local<v8::Array> result = v8::Array::New(list.count()); - for (int ii = 0; ii < list.count(); ++ii) - result->Set(ii, engine->toString(list.at(ii))); - return result; -} - -static v8::Handle<v8::Array> arrayFromVariantList(QV8Engine *engine, const QVariantList &list) -{ - v8::Context::Scope scope(engine->context()); - v8::Local<v8::Array> result = v8::Array::New(list.count()); - for (int ii = 0; ii < list.count(); ++ii) - result->Set(ii, engine->fromVariant(list.at(ii))); - return result; -} - -static v8::Handle<v8::Object> objectFromVariantMap(QV8Engine *engine, const QVariantMap &map) -{ - v8::Context::Scope scope(engine->context()); - v8::Local<v8::Object> object = v8::Object::New(); - for (QVariantMap::ConstIterator iter = map.begin(); iter != map.end(); ++iter) - object->Set(engine->toString(iter.key()), engine->fromVariant(iter.value())); - return object; -} - -Q_CORE_EXPORT QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax); - -v8::Handle<v8::Value> QV8Engine::fromVariant(const QVariant &variant) -{ - int type = variant.userType(); - const void *ptr = variant.constData(); - - if (type < QMetaType::User) { - switch (QMetaType::Type(type)) { - case QMetaType::Void: - return v8::Undefined(); - case QMetaType::Bool: - return v8::Boolean::New(*reinterpret_cast<const bool*>(ptr)); - case QMetaType::Int: - return v8::Integer::New(*reinterpret_cast<const int*>(ptr)); - case QMetaType::UInt: - return v8::Integer::NewFromUnsigned(*reinterpret_cast<const uint*>(ptr)); - case QMetaType::LongLong: - return v8::Number::New(*reinterpret_cast<const qlonglong*>(ptr)); - case QMetaType::ULongLong: - return v8::Number::New(*reinterpret_cast<const qulonglong*>(ptr)); - case QMetaType::Double: - return v8::Number::New(*reinterpret_cast<const double*>(ptr)); - case QMetaType::QString: - return m_stringWrapper.toString(*reinterpret_cast<const QString*>(ptr)); - case QMetaType::Float: - return v8::Number::New(*reinterpret_cast<const float*>(ptr)); - case QMetaType::Short: - return v8::Integer::New(*reinterpret_cast<const short*>(ptr)); - case QMetaType::UShort: - return v8::Integer::NewFromUnsigned(*reinterpret_cast<const unsigned short*>(ptr)); - case QMetaType::Char: - return v8::Integer::New(*reinterpret_cast<const char*>(ptr)); - case QMetaType::UChar: - return v8::Integer::NewFromUnsigned(*reinterpret_cast<const unsigned char*>(ptr)); - case QMetaType::QChar: - return v8::Integer::New((*reinterpret_cast<const QChar*>(ptr)).unicode()); - case QMetaType::QDateTime: - return v8::Date::New(qtDateTimeToJsDate(*reinterpret_cast<const QDateTime *>(ptr))); - case QMetaType::QDate: - return v8::Date::New(qtDateTimeToJsDate(QDateTime(*reinterpret_cast<const QDate *>(ptr)))); - case QMetaType::QTime: - return v8::Date::New(qtDateTimeToJsDate(QDateTime(QDate(1970,1,1), *reinterpret_cast<const QTime *>(ptr)))); - case QMetaType::QRegExp: - return QJSConverter::toRegExp(*reinterpret_cast<const QRegExp *>(ptr)); - case QMetaType::QObjectStar: - case QMetaType::QWidgetStar: - return newQObject(*reinterpret_cast<QObject* const *>(ptr)); - case QMetaType::QStringList: - { - bool succeeded = false; - v8::Handle<v8::Value> retn = m_sequenceWrapper.fromVariant(variant, &succeeded); - if (succeeded) - return retn; - return arrayFromStringList(this, *reinterpret_cast<const QStringList *>(ptr)); - } - case QMetaType::QVariantList: - return arrayFromVariantList(this, *reinterpret_cast<const QVariantList *>(ptr)); - case QMetaType::QVariantMap: - return objectFromVariantMap(this, *reinterpret_cast<const QVariantMap *>(ptr)); - - default: - break; - } - - if (m_engine) { - if (QDeclarativeValueType *vt = QDeclarativeEnginePrivate::get(m_engine)->valueTypes[type]) - return m_valueTypeWrapper.newValueType(variant, vt); - } - - } else { - if (type == qMetaTypeId<QDeclarativeListReference>()) { - typedef QDeclarativeListReferencePrivate QDLRP; - QDLRP *p = QDLRP::get((QDeclarativeListReference*)ptr); - if (p->object) { - return m_listWrapper.newList(p->property, p->propertyType); - } else { - return v8::Null(); - } - } 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); - } else if (type == qMetaTypeId<QList<QObject *> >()) { - // XXX Can this be made more by using Array as a prototype and implementing - // directly against QList<QObject*>? - const QList<QObject *> &list = *(QList<QObject *>*)ptr; - v8::Local<v8::Array> array = v8::Array::New(list.count()); - for (int ii = 0; ii < list.count(); ++ii) - array->Set(ii, newQObject(list.at(ii))); - return array; - } - - bool objOk; - QObject *obj = QDeclarativeMetaType::toQObject(variant, &objOk); - if (objOk) - return newQObject(obj); - - bool succeeded = false; - v8::Handle<v8::Value> retn = m_sequenceWrapper.fromVariant(variant, &succeeded); - if (succeeded) - return retn; - } - - // XXX TODO: To be compatible, we still need to handle: - // + QObjectList - // + QList<int> - - return m_variantWrapper.newVariant(variant); -} - -// A handle scope and context must be entered -v8::Local<v8::Script> QV8Engine::qmlModeCompile(const QString &source, - const QString &fileName, - int lineNumber) -{ - v8::Local<v8::String> v8source = m_stringWrapper.toString(source); - v8::Local<v8::String> v8fileName = m_stringWrapper.toString(fileName); - - v8::ScriptOrigin origin(v8fileName, v8::Integer::New(lineNumber - 1)); - - v8::Local<v8::Script> script = v8::Script::Compile(v8source, &origin, 0, v8::Handle<v8::String>(), - v8::Script::QmlMode); - - return script; -} - -// A handle scope and context must be entered. -// source can be either ascii or utf8. -v8::Local<v8::Script> QV8Engine::qmlModeCompile(const char *source, int sourceLength, - const QString &fileName, - int lineNumber) -{ - if (sourceLength == -1) - sourceLength = strlen(source); - - v8::Local<v8::String> v8source = v8::String::New(source, sourceLength); - v8::Local<v8::String> v8fileName = m_stringWrapper.toString(fileName); - - v8::ScriptOrigin origin(v8fileName, v8::Integer::New(lineNumber - 1)); - - v8::Local<v8::Script> script = v8::Script::Compile(v8source, &origin, 0, v8::Handle<v8::String>(), - v8::Script::QmlMode); - - return script; -} - -QNetworkAccessManager *QV8Engine::networkAccessManager() -{ - return QDeclarativeEnginePrivate::get(m_engine)->getNetworkAccessManager(); -} - -const QStringHash<bool> &QV8Engine::illegalNames() const -{ - return m_illegalNames; -} - -// Requires a handle scope -v8::Local<v8::Array> QV8Engine::getOwnPropertyNames(v8::Handle<v8::Object> o) -{ - // FIXME Newer v8 have API for this function - v8::TryCatch tc; - v8::Handle<v8::Value> args[] = { o }; - v8::Local<v8::Value> r = m_getOwnPropertyNames->Call(global(), 1, args); - if (tc.HasCaught()) - return v8::Array::New(); - else - return v8::Local<v8::Array>::Cast(r); -} - -QDeclarativeContextData *QV8Engine::callingContext() -{ - return m_contextWrapper.callingContext(); -} - -// Converts a JS value to a QVariant. -// Null, Undefined -> QVariant() (invalid) -// Boolean -> QVariant(bool) -// Number -> QVariant(double) -// String -> QVariant(QString) -// Array -> QVariantList(...) -// Date -> QVariant(QDateTime) -// RegExp -> QVariant(QRegExp) -// [Any other object] -> QVariantMap(...) -QVariant QV8Engine::toBasicVariant(v8::Handle<v8::Value> value) -{ - if (value->IsNull() || value->IsUndefined()) - return QVariant(); - if (value->IsBoolean()) - return value->ToBoolean()->Value(); - if (value->IsInt32()) - return value->ToInt32()->Value(); - if (value->IsNumber()) - return value->ToNumber()->Value(); - if (value->IsString()) - return m_stringWrapper.toString(value->ToString()); - if (value->IsDate()) - return qtDateTimeFromJsDate(v8::Handle<v8::Date>::Cast(value)->NumberValue()); - // NOTE: since we convert QTime to JS Date, round trip will change the variant type (to QDateTime)! - - Q_ASSERT(value->IsObject()); - - if (value->IsRegExp()) { - v8::Context::Scope scope(context()); - return QJSConverter::toRegExp(v8::Handle<v8::RegExp>::Cast(value)); - } - if (value->IsArray()) { - v8::Context::Scope scope(context()); - QVariantList rv; - - v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(value); - int length = array->Length(); - for (int ii = 0; ii < length; ++ii) - rv << toVariant(array->Get(ii), -1); - return rv; - } - if (!value->IsFunction()) { - v8::Context::Scope scope(context()); - v8::Handle<v8::Object> object = value->ToObject(); - return variantMapFromJS(object); - } - - return QVariant(); -} - - - -#include <QtGui/qvector3d.h> -#include <QtGui/qvector4d.h> - -struct StaticQtMetaObject : public QObject -{ - static const QMetaObject *get() - { return &static_cast<StaticQtMetaObject*> (0)->staticQtMetaObject; } -}; - -void QV8Engine::initializeGlobal(v8::Handle<v8::Object> global) -{ - using namespace QDeclarativeBuiltinFunctions; - - v8::Local<v8::Object> console = v8::Object::New(); - v8::Local<v8::Function> consoleLogFn = V8FUNCTION(consoleLog, this); - - console->Set(v8::String::New("debug"), consoleLogFn); - console->Set(v8::String::New("log"), consoleLogFn); - console->Set(v8::String::New("info"), consoleLogFn); - console->Set(v8::String::New("warn"), V8FUNCTION(consoleWarn, this)); - console->Set(v8::String::New("error"), V8FUNCTION(consoleError, this)); - console->Set(v8::String::New("assert"), V8FUNCTION(consoleAssert, this)); - - console->Set(v8::String::New("count"), V8FUNCTION(consoleCount, this)); - console->Set(v8::String::New("profile"), V8FUNCTION(consoleProfile, this)); - console->Set(v8::String::New("profileEnd"), V8FUNCTION(consoleProfileEnd, this)); - console->Set(v8::String::New("time"), V8FUNCTION(consoleTime, this)); - console->Set(v8::String::New("timeEnd"), V8FUNCTION(consoleTimeEnd, this)); - console->Set(v8::String::New("trace"), V8FUNCTION(consoleTrace, this)); - console->Set(v8::String::New("exception"), V8FUNCTION(consoleException, this)); - - v8::Local<v8::Object> qt = v8::Object::New(); - - // Set all the enums from the "Qt" namespace - const QMetaObject *qtMetaObject = StaticQtMetaObject::get(); - for (int ii = 0; ii < qtMetaObject->enumeratorCount(); ++ii) { - QMetaEnum enumerator = qtMetaObject->enumerator(ii); - for (int jj = 0; jj < enumerator.keyCount(); ++jj) { - qt->Set(v8::String::New(enumerator.key(jj)), v8::Integer::New(enumerator.value(jj))); - } - } - qt->Set(v8::String::New("Asynchronous"), v8::Integer::New(0)); - qt->Set(v8::String::New("Synchronous"), v8::Integer::New(1)); - - qt->Set(v8::String::New("include"), V8FUNCTION(QV8Include::include, this)); - qt->Set(v8::String::New("isQtObject"), V8FUNCTION(isQtObject, this)); - qt->Set(v8::String::New("rgba"), V8FUNCTION(rgba, this)); - qt->Set(v8::String::New("hsla"), V8FUNCTION(hsla, this)); - qt->Set(v8::String::New("rect"), V8FUNCTION(rect, this)); - qt->Set(v8::String::New("point"), V8FUNCTION(point, this)); - qt->Set(v8::String::New("size"), V8FUNCTION(size, this)); - qt->Set(v8::String::New("vector3d"), V8FUNCTION(vector3d, this)); - qt->Set(v8::String::New("vector4d"), V8FUNCTION(vector4d, this)); - - qt->Set(v8::String::New("formatDate"), V8FUNCTION(formatDate, this)); - qt->Set(v8::String::New("formatTime"), V8FUNCTION(formatTime, this)); - qt->Set(v8::String::New("formatDateTime"), V8FUNCTION(formatDateTime, this)); - - qt->Set(v8::String::New("openUrlExternally"), V8FUNCTION(openUrlExternally, this)); - qt->Set(v8::String::New("fontFamilies"), V8FUNCTION(fontFamilies, this)); - qt->Set(v8::String::New("md5"), V8FUNCTION(md5, this)); - qt->Set(v8::String::New("btoa"), V8FUNCTION(btoa, this)); - qt->Set(v8::String::New("atob"), V8FUNCTION(atob, this)); - qt->Set(v8::String::New("resolvedUrl"), V8FUNCTION(resolvedUrl, this)); - qt->Set(v8::String::New("locale"), V8FUNCTION(locale, this)); - - if (m_engine) { - qt->Set(v8::String::New("application"), newQObject(new QDeclarativeApplication(m_engine))); - qt->Set(v8::String::New("inputMethod"), newQObject(qGuiApp->inputMethod(), CppOwnership)); - qt->Set(v8::String::New("lighter"), V8FUNCTION(lighter, this)); - qt->Set(v8::String::New("darker"), V8FUNCTION(darker, this)); - qt->Set(v8::String::New("tint"), V8FUNCTION(tint, this)); - qt->Set(v8::String::New("quit"), V8FUNCTION(quit, this)); - qt->Set(v8::String::New("createQmlObject"), V8FUNCTION(createQmlObject, this)); - qt->Set(v8::String::New("createComponent"), V8FUNCTION(createComponent, this)); - } - - global->Set(v8::String::New("qsTranslate"), V8FUNCTION(qsTranslate, this)); - global->Set(v8::String::New("QT_TRANSLATE_NOOP"), V8FUNCTION(qsTranslateNoOp, this)); - global->Set(v8::String::New("qsTr"), V8FUNCTION(qsTr, this)); - global->Set(v8::String::New("QT_TR_NOOP"), V8FUNCTION(qsTrNoOp, this)); - global->Set(v8::String::New("qsTrId"), V8FUNCTION(qsTrId, this)); - global->Set(v8::String::New("QT_TRID_NOOP"), V8FUNCTION(qsTrIdNoOp, this)); - - global->Set(v8::String::New("print"), consoleLogFn); - global->Set(v8::String::New("console"), console); - global->Set(v8::String::New("Qt"), qt); - global->Set(v8::String::New("gc"), V8FUNCTION(QDeclarativeBuiltinFunctions::gc, this)); - - { -#define STRING_ARG "(function(stringArg) { "\ - " String.prototype.arg = (function() {"\ - " return stringArg.apply(this, arguments);"\ - " })"\ - "})" - - v8::Local<v8::Script> registerArg = v8::Script::New(v8::String::New(STRING_ARG), 0, 0, v8::Handle<v8::String>(), v8::Script::NativeMode); - v8::Local<v8::Value> result = registerArg->Run(); - Q_ASSERT(result->IsFunction()); - v8::Local<v8::Function> registerArgFunc = v8::Local<v8::Function>::Cast(result); - v8::Handle<v8::Value> args = V8FUNCTION(stringArg, this); - registerArgFunc->Call(v8::Local<v8::Object>::Cast(registerArgFunc), 1, &args); -#undef STRING_ARG - } - - QDeclarativeLocale::registerStringLocaleCompare(this); - QDeclarativeDateExtension::registerExtension(this); - QDeclarativeNumberExtension::registerExtension(this); - - qt_add_domexceptions(this); - m_xmlHttpRequestData = qt_add_qmlxmlhttprequest(this); - - qt_add_sqlexceptions(this); - - { - v8::Handle<v8::Value> args[] = { global }; - v8::Local<v8::Value> names = m_getOwnPropertyNames->Call(global, 1, args); - v8::Local<v8::Array> namesArray = v8::Local<v8::Array>::Cast(names); - for (quint32 ii = 0; ii < namesArray->Length(); ++ii) - m_illegalNames.insert(toString(namesArray->Get(ii)), true); - } - - { -#define FREEZE_SOURCE "(function freeze_recur(obj) { "\ - " if (Qt.isQtObject(obj)) return;"\ - " if (obj != Function.connect && obj != Function.disconnect && "\ - " obj instanceof Object) {"\ - " var properties = Object.getOwnPropertyNames(obj);"\ - " for (var prop in properties) { "\ - " if (prop == \"connect\" || prop == \"disconnect\") {"\ - " Object.freeze(obj[prop]); "\ - " continue;"\ - " }"\ - " freeze_recur(obj[prop]);"\ - " }"\ - " }"\ - " if (obj instanceof Object) {"\ - " Object.freeze(obj);"\ - " }"\ - "})" - - v8::Local<v8::Script> freeze = v8::Script::New(v8::String::New(FREEZE_SOURCE)); - v8::Local<v8::Value> result = freeze->Run(); - Q_ASSERT(result->IsFunction()); - m_freezeObject = qPersistentNew(v8::Local<v8::Function>::Cast(result)); -#undef FREEZE_SOURCE - } -} - -void QV8Engine::freezeObject(v8::Handle<v8::Value> value) -{ - v8::Handle<v8::Value> args[] = { value }; - m_freezeObject->Call(global(), 1, args); -} - -void QV8Engine::gc() -{ - v8::V8::LowMemoryNotification(); - while (!v8::V8::IdleNotification()) {} -} - -#ifdef QML_GLOBAL_HANDLE_DEBUGGING -#include <QtCore/qthreadstorage.h> -static QThreadStorage<QSet<void *> *> QV8Engine_activeHandles; - -void QV8Engine::registerHandle(void *handle) -{ - if (!handle) { - qWarning("Attempting to register a null handle"); - return; - } - - if (!QV8Engine_activeHandles.hasLocalData()) - QV8Engine_activeHandles.setLocalData(new QSet<void *>); - - if (QV8Engine_activeHandles.localData()->contains(handle)) { - qFatal("Handle %p already alive", handle); - } else { - QV8Engine_activeHandles.localData()->insert(handle); - } -} - -void QV8Engine::releaseHandle(void *handle) -{ - if (!handle) - return; - - if (!QV8Engine_activeHandles.hasLocalData()) - QV8Engine_activeHandles.setLocalData(new QSet<void *>); - - if (QV8Engine_activeHandles.localData()->contains(handle)) { - QV8Engine_activeHandles.localData()->remove(handle); - } else { - qFatal("Handle %p already dead", handle); - } -} -#endif - -struct QV8EngineRegistrationData -{ - QV8EngineRegistrationData() : extensionCount(0) {} - - QMutex mutex; - int extensionCount; -}; -Q_GLOBAL_STATIC(QV8EngineRegistrationData, registrationData); - -QMutex *QV8Engine::registrationMutex() -{ - return ®istrationData()->mutex; -} - -int QV8Engine::registerExtension() -{ - return registrationData()->extensionCount++; -} - -void QV8Engine::setExtensionData(int index, Deletable *data) -{ - if (m_extensionData.count() <= index) - m_extensionData.resize(index + 1); - - if (m_extensionData.at(index)) - delete m_extensionData.at(index); - - m_extensionData[index] = data; -} - -double QV8Engine::qtDateTimeToJsDate(const QDateTime &dt) -{ - // from QScriptEngine::DateTimeToMs() - if (!dt.isValid()) { - return qSNaN(); - } - QDateTime utc = dt.toUTC(); - QDate date = utc.date(); - QTime time = utc.time(); - QV8DateConverter::JSC::GregorianDateTime tm; - tm.year = date.year() - 1900; - tm.month = date.month() - 1; - tm.monthDay = date.day(); - tm.weekDay = date.dayOfWeek(); - tm.yearDay = date.dayOfYear(); - tm.hour = time.hour(); - tm.minute = time.minute(); - tm.second = time.second(); - return QV8DateConverter::JSC::gregorianDateTimeToMS(tm, time.msec()); -} - -v8::Persistent<v8::Object> *QV8Engine::findOwnerAndStrength(QObject *object, bool *shouldBeStrong) -{ - QObject *parent = object->parent(); - if (!parent) { - // if the object has JS ownership, the object's v8object owns the lifetime of the persistent value. - if (QDeclarativeEngine::objectOwnership(object) == QDeclarativeEngine::JavaScriptOwnership) { - *shouldBeStrong = false; - return &(QDeclarativeData::get(object)->v8object); - } - - // no parent, and has CPP ownership - doesn't have an implicit parent. - *shouldBeStrong = true; - return 0; - } - - // if it is owned by CPP, it's root parent may still be owned by JS. - // in that case, the owner of the persistent handle is the root parent's v8object. - while (parent->parent()) - parent = parent->parent(); - - if (QDeclarativeEngine::objectOwnership(parent) == QDeclarativeEngine::JavaScriptOwnership) { - // root parent is owned by JS. It's v8object owns the persistent value in question. - *shouldBeStrong = false; - return &(QDeclarativeData::get(parent)->v8object); - } else { - // root parent has CPP ownership. The persistent value should not be made weak. - *shouldBeStrong = true; - return 0; - } -} - -QDateTime QV8Engine::qtDateTimeFromJsDate(double jsDate) -{ - // from QScriptEngine::MsToDateTime() - if (qIsNaN(jsDate)) - return QDateTime(); - QV8DateConverter::JSC::GregorianDateTime tm; - QV8DateConverter::JSC::msToGregorianDateTime(jsDate, tm); - - // from QScriptEngine::MsFromTime() - int ms = int(::fmod(jsDate, 1000.0)); - if (ms < 0) - ms += int(1000.0); - - QDateTime convertedUTC = QDateTime(QDate(tm.year + 1900, tm.month + 1, tm.monthDay), - QTime(tm.hour, tm.minute, tm.second, ms), Qt::UTC); - return convertedUTC.toLocalTime(); -} - -void QV8Engine::addRelationshipForGC(QObject *object, v8::Persistent<v8::Value> handle) -{ - if (handle.IsEmpty()) - return; - - bool handleShouldBeStrong = false; - v8::Persistent<v8::Object> *implicitOwner = findOwnerAndStrength(object, &handleShouldBeStrong); - if (handleShouldBeStrong) { - v8::V8::AddImplicitReferences(m_strongReferencer, &handle, 1); - } else if (!implicitOwner->IsEmpty()) { - v8::V8::AddImplicitReferences(*implicitOwner, &handle, 1); - } -} - -void QV8Engine::addRelationshipForGC(QObject *object, QObject *other) -{ - bool handleShouldBeStrong = false; - v8::Persistent<v8::Object> *implicitOwner = findOwnerAndStrength(object, &handleShouldBeStrong); - v8::Persistent<v8::Value> handle = QDeclarativeData::get(other, true)->v8object; - if (handleShouldBeStrong) { - v8::V8::AddImplicitReferences(m_strongReferencer, &handle, 1); - } else if (!implicitOwner->IsEmpty()) { - v8::V8::AddImplicitReferences(*implicitOwner, &handle, 1); - } -} - -static QThreadStorage<QV8Engine::ThreadData*> perThreadEngineData; - -bool QV8Engine::hasThreadData() -{ - return perThreadEngineData.hasLocalData(); -} - -QV8Engine::ThreadData *QV8Engine::threadData() -{ - Q_ASSERT(perThreadEngineData.hasLocalData()); - return perThreadEngineData.localData(); -} - -void QV8Engine::ensurePerThreadIsolate() -{ - if (!perThreadEngineData.hasLocalData()) - perThreadEngineData.setLocalData(new ThreadData); -} - -void QV8Engine::initDeclarativeGlobalObject() -{ - v8::HandleScope handels; - v8::Context::Scope contextScope(m_context); - initializeGlobal(m_context->Global()); - freezeObject(m_context->Global()); -} - -void QV8Engine::setEngine(QDeclarativeEngine *engine) -{ - m_engine = engine; - initDeclarativeGlobalObject(); -} - -void QV8Engine::setException(v8::Handle<v8::Value> value, v8::Handle<v8::Message> msg) -{ - m_exception.set(value, msg); -} - -v8::Handle<v8::Value> QV8Engine::throwException(v8::Handle<v8::Value> value) -{ - setException(value); - v8::ThrowException(value); - return value; -} - -void QV8Engine::clearExceptions() -{ - m_exception.clear(); -} - -v8::Handle<v8::Value> QV8Engine::uncaughtException() const -{ - if (!hasUncaughtException()) - return v8::Handle<v8::Value>(); - return m_exception; -} - -bool QV8Engine::hasUncaughtException() const -{ - return m_exception; -} - -int QV8Engine::uncaughtExceptionLineNumber() const -{ - return m_exception.lineNumber(); -} - -QStringList QV8Engine::uncaughtExceptionBacktrace() const -{ - return m_exception.backtrace(); -} - -/*! - \internal - Save the current exception on stack so it can be set again later. - \sa QV8Engine::restoreException -*/ -void QV8Engine::saveException() -{ - m_exception.push(); -} - -/*! - \internal - Load a saved exception from stack. Current exception, if exists will be dropped - \sa QV8Engine::saveException -*/ -void QV8Engine::restoreException() -{ - m_exception.pop(); -} - -QV8Engine::Exception::Exception() {} - -QV8Engine::Exception::~Exception() -{ - Q_ASSERT_X(m_stack.isEmpty(), Q_FUNC_INFO, "Some saved exceptions left. Asymetric pop/push found."); - clear(); -} - -void QV8Engine::Exception::set(v8::Handle<v8::Value> value, v8::Handle<v8::Message> message) -{ - Q_ASSERT_X(!value.IsEmpty(), Q_FUNC_INFO, "Throwing an empty value handle is highly suspected"); - clear(); - m_value = v8::Persistent<v8::Value>::New(value); - m_message = v8::Persistent<v8::Message>::New(message); -} - -void QV8Engine::Exception::clear() -{ - m_value.Dispose(); - m_value.Clear(); - m_message.Dispose(); - m_message.Clear(); -} - -QV8Engine::Exception::operator bool() const -{ - return !m_value.IsEmpty(); -} - -QV8Engine::Exception::operator v8::Handle<v8::Value>() const -{ - Q_ASSERT(*this); - return m_value; -} - -int QV8Engine::Exception::lineNumber() const -{ - if (m_message.IsEmpty()) - return -1; - return m_message->GetLineNumber(); -} - -QStringList QV8Engine::Exception::backtrace() const -{ - if (m_message.IsEmpty()) - return QStringList(); - - QStringList backtrace; - v8::Handle<v8::StackTrace> trace = m_message->GetStackTrace(); - if (trace.IsEmpty()) - // FIXME it should not happen (SetCaptureStackTraceForUncaughtExceptions is called). - return QStringList(); - - for (int i = 0; i < trace->GetFrameCount(); ++i) { - v8::Local<v8::StackFrame> frame = trace->GetFrame(i); - backtrace.append(QJSConverter::toString(frame->GetFunctionName())); - backtrace.append(QJSConverter::toString(frame->GetFunctionName())); - backtrace.append(QString::fromAscii("()@")); - backtrace.append(QJSConverter::toString(frame->GetScriptName())); - backtrace.append(QString::fromAscii(":")); - backtrace.append(QString::number(frame->GetLineNumber())); - } - return backtrace; -} - -void QV8Engine::Exception::push() -{ - m_stack.push(qMakePair(m_value, m_message)); - m_value.Clear(); - m_message.Clear(); -} - -void QV8Engine::Exception::pop() -{ - Q_ASSERT_X(!m_stack.empty(), Q_FUNC_INFO, "Attempt to load unsaved exception found"); - ValueMessagePair pair = m_stack.pop(); - clear(); - m_value = pair.first; - m_message = pair.second; -} - - -// Converts a QVariantList to JS. -// The result is a new Array object with length equal to the length -// of the QVariantList, and the elements being the QVariantList's -// elements converted to JS, recursively. -v8::Local<v8::Array> QV8Engine::variantListToJS(const QVariantList &lst) -{ - v8::Local<v8::Array> result = v8::Array::New(lst.size()); - for (int i = 0; i < lst.size(); ++i) - result->Set(i, variantToJS(lst.at(i))); - return result; -} - -// Converts a JS Array object to a QVariantList. -// The result is a QVariantList with length equal to the length -// of the JS Array, and elements being the JS Array's elements -// converted to QVariants, recursively. -QVariantList QV8Engine::variantListFromJS(v8::Handle<v8::Array> jsArray) -{ - QVariantList result; - int hash = jsArray->GetIdentityHash(); - if (visitedConversionObjects.contains(hash)) - return result; // Avoid recursion. - v8::HandleScope handleScope; - visitedConversionObjects.insert(hash); - uint32_t length = jsArray->Length(); - for (uint32_t i = 0; i < length; ++i) - result.append(variantFromJS(jsArray->Get(i))); - visitedConversionObjects.remove(hash); - return result; -} - -// Converts a QVariantMap to JS. -// The result is a new Object object with property names being -// the keys of the QVariantMap, and values being the values of -// the QVariantMap converted to JS, recursively. -v8::Local<v8::Object> QV8Engine::variantMapToJS(const QVariantMap &vmap) -{ - v8::Local<v8::Object> result = v8::Object::New(); - QVariantMap::const_iterator it; - for (it = vmap.constBegin(); it != vmap.constEnd(); ++it) - result->Set(QJSConverter::toString(it.key()), variantToJS(it.value())); - return result; -} - -// Converts a JS Object to a QVariantMap. -// The result is a QVariantMap with keys being the property names -// of the object, and values being the values of the JS object's -// properties converted to QVariants, recursively. -QVariantMap QV8Engine::variantMapFromJS(v8::Handle<v8::Object> jsObject) -{ - QVariantMap result; - - v8::HandleScope handleScope; - v8::Handle<v8::Array> propertyNames = jsObject->GetPropertyNames(); - uint32_t length = propertyNames->Length(); - if (length == 0) - return result; - - int hash = jsObject->GetIdentityHash(); - if (visitedConversionObjects.contains(hash)) - return result; // Avoid recursion. - - visitedConversionObjects.insert(hash); - // TODO: Only object's own property names. Include non-enumerable properties. - for (uint32_t i = 0; i < length; ++i) { - v8::Handle<v8::Value> name = propertyNames->Get(i); - result.insert(QJSConverter::toString(name->ToString()), variantFromJS(jsObject->Get(name))); - } - visitedConversionObjects.remove(hash); - return result; -} - -// Converts the meta-type defined by the given type and data to JS. -// Returns the value if conversion succeeded, an empty handle otherwise. -v8::Handle<v8::Value> QV8Engine::metaTypeToJS(int type, const void *data) -{ - Q_ASSERT(data != 0); - v8::Handle<v8::Value> result; - - // check if it's one of the types we know - switch (QMetaType::Type(type)) { - case QMetaType::Void: - return v8::Undefined(); - case QMetaType::Bool: - return v8::Boolean::New(*reinterpret_cast<const bool*>(data)); - case QMetaType::Int: - return v8::Int32::New(*reinterpret_cast<const int*>(data)); - case QMetaType::UInt: - return v8::Uint32::New(*reinterpret_cast<const uint*>(data)); - case QMetaType::LongLong: - return v8::Number::New(double(*reinterpret_cast<const qlonglong*>(data))); - case QMetaType::ULongLong: -#if defined(Q_OS_WIN) && defined(_MSC_FULL_VER) && _MSC_FULL_VER <= 12008804 -#pragma message("** NOTE: You need the Visual Studio Processor Pack to compile support for 64bit unsigned integers.") - return v8::Number::New(double((qlonglong)*reinterpret_cast<const qulonglong*>(data))); -#elif defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET) - return v8::Number::New(double((qlonglong)*reinterpret_cast<const qulonglong*>(data))); -#else - return v8::Number::New(double(*reinterpret_cast<const qulonglong*>(data))); -#endif - case QMetaType::Double: - return v8::Number::New(double(*reinterpret_cast<const double*>(data))); - case QMetaType::QString: - return QJSConverter::toString(*reinterpret_cast<const QString*>(data)); - case QMetaType::Float: - return v8::Number::New(*reinterpret_cast<const float*>(data)); - case QMetaType::Short: - return v8::Int32::New(*reinterpret_cast<const short*>(data)); - case QMetaType::UShort: - return v8::Uint32::New(*reinterpret_cast<const unsigned short*>(data)); - case QMetaType::Char: - return v8::Int32::New(*reinterpret_cast<const char*>(data)); - case QMetaType::UChar: - return v8::Uint32::New(*reinterpret_cast<const unsigned char*>(data)); - case QMetaType::QChar: - return v8::Uint32::New((*reinterpret_cast<const QChar*>(data)).unicode()); - case QMetaType::QStringList: - result = QJSConverter::toStringList(*reinterpret_cast<const QStringList *>(data)); - break; - case QMetaType::QVariantList: - result = variantListToJS(*reinterpret_cast<const QVariantList *>(data)); - break; - case QMetaType::QVariantMap: - result = variantMapToJS(*reinterpret_cast<const QVariantMap *>(data)); - break; - case QMetaType::QDateTime: - result = QJSConverter::toDateTime(*reinterpret_cast<const QDateTime *>(data)); - break; - case QMetaType::QDate: - result = QJSConverter::toDateTime(QDateTime(*reinterpret_cast<const QDate *>(data))); - break; - case QMetaType::QRegExp: - result = QJSConverter::toRegExp(*reinterpret_cast<const QRegExp *>(data)); - break; - case QMetaType::QObjectStar: - case QMetaType::QWidgetStar: - result = newQObject(*reinterpret_cast<QObject* const *>(data)); - break; - case QMetaType::QVariant: - result = variantToJS(*reinterpret_cast<const QVariant*>(data)); - break; - default: - if (type == qMetaTypeId<QJSValue>()) { - return QJSValuePrivate::get(*reinterpret_cast<const QJSValue*>(data))->asV8Value(this); - } else { - QByteArray typeName = QMetaType::typeName(type); - if (typeName.endsWith('*') && !*reinterpret_cast<void* const *>(data)) { - return v8::Null(); - } else { - // Fall back to wrapping in a QVariant. - result = newVariant(QVariant(type, data)); - } - } - } - return result; -} - -// Converts a JS value to a meta-type. -// data must point to a place that can store a value of the given type. -// Returns true if conversion succeeded, false otherwise. -bool QV8Engine::metaTypeFromJS(v8::Handle<v8::Value> value, int type, void *data) { - // check if it's one of the types we know - switch (QMetaType::Type(type)) { - case QMetaType::Bool: - *reinterpret_cast<bool*>(data) = value->ToBoolean()->Value(); - return true; - case QMetaType::Int: - *reinterpret_cast<int*>(data) = value->ToInt32()->Value(); - return true; - case QMetaType::UInt: - *reinterpret_cast<uint*>(data) = value->ToUint32()->Value(); - return true; - case QMetaType::LongLong: - *reinterpret_cast<qlonglong*>(data) = qlonglong(value->ToInteger()->Value()); - return true; - case QMetaType::ULongLong: - *reinterpret_cast<qulonglong*>(data) = qulonglong(value->ToInteger()->Value()); - return true; - case QMetaType::Double: - *reinterpret_cast<double*>(data) = value->ToNumber()->Value(); - return true; - case QMetaType::QString: - if (value->IsUndefined() || value->IsNull()) - *reinterpret_cast<QString*>(data) = QString(); - else - *reinterpret_cast<QString*>(data) = QJSConverter::toString(value->ToString()); - return true; - case QMetaType::Float: - *reinterpret_cast<float*>(data) = value->ToNumber()->Value(); - return true; - case QMetaType::Short: - *reinterpret_cast<short*>(data) = short(value->ToInt32()->Value()); - return true; - case QMetaType::UShort: - *reinterpret_cast<unsigned short*>(data) = ushort(value->ToInt32()->Value()); // ### QScript::ToUInt16() - return true; - case QMetaType::Char: - *reinterpret_cast<char*>(data) = char(value->ToInt32()->Value()); - return true; - case QMetaType::UChar: - *reinterpret_cast<unsigned char*>(data) = (unsigned char)(value->ToInt32()->Value()); - return true; - case QMetaType::QChar: - if (value->IsString()) { - QString str = QJSConverter::toString(v8::Handle<v8::String>::Cast(value)); - *reinterpret_cast<QChar*>(data) = str.isEmpty() ? QChar() : str.at(0); - } else { - *reinterpret_cast<QChar*>(data) = QChar(ushort(value->ToInt32()->Value())); // ### QScript::ToUInt16() - } - return true; - case QMetaType::QDateTime: - if (value->IsDate()) { - *reinterpret_cast<QDateTime *>(data) = QJSConverter::toDateTime(v8::Handle<v8::Date>::Cast(value)); - return true; - } break; - case QMetaType::QDate: - if (value->IsDate()) { - *reinterpret_cast<QDate *>(data) = QJSConverter::toDateTime(v8::Handle<v8::Date>::Cast(value)).date(); - return true; - } break; - case QMetaType::QRegExp: - if (value->IsRegExp()) { - *reinterpret_cast<QRegExp *>(data) = QJSConverter::toRegExp(v8::Handle<v8::RegExp>::Cast(value)); - return true; - } break; - case QMetaType::QObjectStar: - if (isQObject(value) || value->IsNull()) { - *reinterpret_cast<QObject* *>(data) = qtObjectFromJS(value); - return true; - } break; - case QMetaType::QWidgetStar: - if (isQObject(value) || value->IsNull()) { - QObject *qo = qtObjectFromJS(value); - if (!qo || qo->isWidgetType()) { - *reinterpret_cast<QWidget* *>(data) = reinterpret_cast<QWidget*>(qo); - return true; - } - } break; - case QMetaType::QStringList: - if (value->IsArray()) { - *reinterpret_cast<QStringList *>(data) = QJSConverter::toStringList(v8::Handle<v8::Array>::Cast(value)); - return true; - } break; - case QMetaType::QVariantList: - if (value->IsArray()) { - *reinterpret_cast<QVariantList *>(data) = variantListFromJS(v8::Handle<v8::Array>::Cast(value)); - return true; - } break; - case QMetaType::QVariantMap: - if (value->IsObject()) { - *reinterpret_cast<QVariantMap *>(data) = variantMapFromJS(v8::Handle<v8::Object>::Cast(value)); - return true; - } break; - case QMetaType::QVariant: - *reinterpret_cast<QVariant*>(data) = variantFromJS(value); - return true; - default: - ; - } - -#if 0 - if (isQtVariant(value)) { - const QVariant &var = variantValue(value); - // ### Enable once constructInPlace() is in qt master. - if (var.userType() == type) { - QMetaType::constructInPlace(type, data, var.constData()); - return true; - } - if (var.canConvert(QVariant::Type(type))) { - QVariant vv = var; - vv.convert(QVariant::Type(type)); - Q_ASSERT(vv.userType() == type); - QMetaType::constructInPlace(type, data, vv.constData()); - return true; - } - - } -#endif - - // Try to use magic; for compatibility with qscriptvalue_cast. - - QByteArray name = QMetaType::typeName(type); - if (convertToNativeQObject(value, name, reinterpret_cast<void* *>(data))) - return true; - if (isVariant(value) && name.endsWith('*')) { - int valueType = QMetaType::type(name.left(name.size()-1)); - QVariant &var = variantValue(value); - if (valueType == var.userType()) { - // We have T t, T* is requested, so return &t. - *reinterpret_cast<void* *>(data) = var.data(); - return true; - } else { - // Look in the prototype chain. - v8::Handle<v8::Value> proto = value->ToObject()->GetPrototype(); - while (proto->IsObject()) { - bool canCast = false; - if (isVariant(proto)) { - canCast = (type == variantValue(proto).userType()) - || (valueType && (valueType == variantValue(proto).userType())); - } - else if (isQObject(proto)) { - QByteArray className = name.left(name.size()-1); - if (QObject *qobject = qtObjectFromJS(proto)) - canCast = qobject->qt_metacast(className) != 0; - } - if (canCast) { - QByteArray varTypeName = QMetaType::typeName(var.userType()); - if (varTypeName.endsWith('*')) - *reinterpret_cast<void* *>(data) = *reinterpret_cast<void* *>(var.data()); - else - *reinterpret_cast<void* *>(data) = var.data(); - return true; - } - proto = proto->ToObject()->GetPrototype(); - } - } - } else if (value->IsNull() && name.endsWith('*')) { - *reinterpret_cast<void* *>(data) = 0; - return true; - } else if (type == qMetaTypeId<QJSValue>()) { - *reinterpret_cast<QJSValue*>(data) = QJSValuePrivate::get(new QJSValuePrivate(this, value)); - return true; - } - - return false; -} - -// Converts a QVariant to JS. -v8::Handle<v8::Value> QV8Engine::variantToJS(const QVariant &value) -{ - return metaTypeToJS(value.userType(), value.constData()); -} - -// Converts a JS value to a QVariant. -// Null, Undefined -> QVariant() (invalid) -// Boolean -> QVariant(bool) -// Number -> QVariant(double) -// String -> QVariant(QString) -// Array -> QVariantList(...) -// Date -> QVariant(QDateTime) -// RegExp -> QVariant(QRegExp) -// [Any other object] -> QVariantMap(...) -QVariant QV8Engine::variantFromJS(v8::Handle<v8::Value> value) -{ - Q_ASSERT(!value.IsEmpty()); - if (value->IsNull() || value->IsUndefined()) - return QVariant(); - if (value->IsBoolean()) - return value->ToBoolean()->Value(); - if (value->IsInt32()) - return value->ToInt32()->Value(); - if (value->IsNumber()) - return value->ToNumber()->Value(); - if (value->IsString()) - return QJSConverter::toString(value->ToString()); - Q_ASSERT(value->IsObject()); - if (value->IsArray()) - return variantListFromJS(v8::Handle<v8::Array>::Cast(value)); - if (value->IsDate()) - return QJSConverter::toDateTime(v8::Handle<v8::Date>::Cast(value)); - if (value->IsRegExp()) - return QJSConverter::toRegExp(v8::Handle<v8::RegExp>::Cast(value)); - if (isVariant(value)) - return variantValue(value); - if (isQObject(value)) - return qVariantFromValue(qtObjectFromJS(value)); - return variantMapFromJS(value->ToObject()); -} - -bool QV8Engine::convertToNativeQObject(v8::Handle<v8::Value> value, - const QByteArray &targetType, - void **result) -{ - if (!targetType.endsWith('*')) - return false; - if (QObject *qobject = qtObjectFromJS(value)) { - int start = targetType.startsWith("const ") ? 6 : 0; - QByteArray className = targetType.mid(start, targetType.size()-start-1); - if (void *instance = qobject->qt_metacast(className)) { - *result = instance; - return true; - } - } - return false; -} - -QObject *QV8Engine::qtObjectFromJS(v8::Handle<v8::Value> value) -{ - if (!value->IsObject()) - return 0; - - QV8ObjectResource *r = (QV8ObjectResource *)value->ToObject()->GetExternalResource(); - if (!r) - return 0; - QV8ObjectResource::ResourceType type = r->resourceType(); - if (type == QV8ObjectResource::QObjectType) - return qobjectWrapper()->toQObject(r); - else if (type == QV8ObjectResource::VariantType) { - QVariant variant = variantWrapper()->toVariant(r); - int type = variant.userType(); - if ((type == QMetaType::QObjectStar) || (type == QMetaType::QWidgetStar)) - return *reinterpret_cast<QObject* const *>(variant.constData()); - } - return 0; -} - - -QVariant &QV8Engine::variantValue(v8::Handle<v8::Value> value) -{ - return variantWrapper()->variantValue(value); -} - -// Creates a QVariant wrapper object. -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) -{ - v8::HandleScope handleScope; - - clearExceptions(); - if (script.IsEmpty()) { - 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); - } - setException(exception, tryCatch.Message()); - return new QJSValuePrivate(this, exception); - } - v8::Handle<v8::Value> result; - result = script->Run(); - if (result.IsEmpty()) { - v8::Handle<v8::Value> exception = tryCatch.Exception(); - // TODO: figure out why v8 doesn't always produce an exception value - //Q_ASSERT(!exception.IsEmpty()); - if (exception.IsEmpty()) - exception = v8::Exception::Error(v8::String::New("missing exception value")); - setException(exception, tryCatch.Message()); - return new QJSValuePrivate(this, exception); - } - return new QJSValuePrivate(this, result); -} - -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)); -} - -QScriptPassPointer<QJSValuePrivate> QV8Engine::newArray(uint length) -{ - return new QJSValuePrivate(this, v8::Array::New(length)); -} - -void QV8Engine::emitSignalHandlerException() -{ - emit q->signalHandlerException(scriptValueFromInternal(uncaughtException())); -} - -void QV8Engine::startTimer(const QString &timerName) -{ - if (!m_time.isValid()) - m_time.start(); - m_startedTimers[timerName] = m_time.elapsed(); -} - -qint64 QV8Engine::stopTimer(const QString &timerName, bool *wasRunning) -{ - if (!m_startedTimers.contains(timerName)) { - *wasRunning = false; - return 0; - } - *wasRunning = true; - qint64 startedAt = m_startedTimers.take(timerName); - return m_time.elapsed() - startedAt; -} - -int QV8Engine::consoleCountHelper(const QString &file, int line, int column) -{ - const QString key = file + QString::number(line) + QString::number(column); - int number = m_consoleCount.value(key, 0); - number++; - m_consoleCount.insert(key, number); - return number; -} - -void QV8GCCallback::registerGcPrologueCallback() -{ - QV8Engine::ThreadData *td = QV8Engine::threadData(); - if (!td->gcPrologueCallbackRegistered) { - td->gcPrologueCallbackRegistered = true; - v8::V8::AddGCPrologueCallback(QV8GCCallback::garbageCollectorPrologueCallback, v8::kGCTypeMarkSweepCompact); - } -} - -QV8GCCallback::Node::Node(PrologueCallback callback) - : prologueCallback(callback) -{ -} - -QV8GCCallback::Node::~Node() -{ - node.remove(); -} - -/* - Ensure that each persistent handle is strong if it has CPP ownership - and has no implicitly JS owned object owner in its parent chain, and - weak otherwise. - - Any weak handle whose parent object is still alive will have an implicit - reference (between the parent and the handle) added, so that it will - not be collected. - - Note that this callback is registered only for kGCTypeMarkSweepCompact - collection cycles, as it is during collection cycles of that type - in which weak persistent handle callbacks are called when required. - */ -void QV8GCCallback::garbageCollectorPrologueCallback(v8::GCType, v8::GCCallbackFlags) -{ - if (!QV8Engine::hasThreadData()) - return; - - QV8Engine::ThreadData *td = QV8Engine::threadData(); - QV8GCCallback::Node *currNode = td->gcCallbackNodes.first(); - - while (currNode) { - // The client which adds itself to the list is responsible - // for maintaining the correct implicit references in the - // specified callback. - currNode->prologueCallback(currNode); - currNode = td->gcCallbackNodes.next(currNode); - } -} - -void QV8GCCallback::addGcCallbackNode(QV8GCCallback::Node *node) -{ - QV8Engine::ThreadData *td = QV8Engine::threadData(); - td->gcCallbackNodes.insert(node); -} - -QV8Engine::ThreadData::ThreadData() - : gcPrologueCallbackRegistered(false) -{ - if (!v8::Isolate::GetCurrent()) { - isolate = v8::Isolate::New(); - isolate->Enter(); - } else { - isolate = 0; - } -} - -QV8Engine::ThreadData::~ThreadData() -{ - if (isolate) { - isolate->Exit(); - isolate->Dispose(); - isolate = 0; - } -} - -QT_END_NAMESPACE - diff --git a/src/declarative/qml/v8/qv8engine_impl_p.h b/src/declarative/qml/v8/qv8engine_impl_p.h deleted file mode 100644 index 349589680a..0000000000 --- a/src/declarative/qml/v8/qv8engine_impl_p.h +++ /dev/null @@ -1,155 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL-ONLY$ -** GNU Lesser General Public License Usage -** 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. -** -** If you have questions regarding the use of this file, please contact -** us via http://www.qt-project.org/. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QV8ENGINE_IMPL_P_H -#define QV8ENGINE_IMPL_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qv8engine_p.h" -#include "qjsvalue_p.h" -#include "qjsconverter_p.h" -#include "qjsvalueiterator_p.h" - -QT_BEGIN_NAMESPACE - -inline v8::Handle<v8::Value> QV8Engine::makeJSValue(bool value) -{ - return value ? v8::True() : v8::False(); -} - -inline v8::Local<v8::Value> QV8Engine::makeJSValue(int value) -{ - return v8::Integer::New(value); -} - -inline v8::Local<v8::Value> QV8Engine::makeJSValue(uint value) -{ - return v8::Integer::NewFromUnsigned(value); -} - -inline v8::Local<v8::Value> QV8Engine::makeJSValue(double value) -{ - return v8::Number::New(value); -} - -inline 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) -{ - 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, int lineNumber) -{ - v8::TryCatch tryCatch; - v8::ScriptOrigin scriptOrigin(QJSConverter::toString(fileName), v8::Integer::New(lineNumber - 1)); - v8::Handle<v8::Script> script; - script = v8::Script::Compile(QJSConverter::toString(program), &scriptOrigin); - 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("")); - setException(error); - return new QJSValuePrivate(this, error); - } - return evaluate(script, tryCatch); -} - -QT_END_NAMESPACE - -#endif // QV8ENGINE_IMPL_P_H diff --git a/src/declarative/qml/v8/qv8engine_p.h b/src/declarative/qml/v8/qv8engine_p.h deleted file mode 100644 index 4bfb991eae..0000000000 --- a/src/declarative/qml/v8/qv8engine_p.h +++ /dev/null @@ -1,631 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QDECLARATIVEV8ENGINE_P_H -#define QDECLARATIVEV8ENGINE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/qglobal.h> -#include <QtCore/qvariant.h> -#include <QtCore/qset.h> -#include <QtCore/qmutex.h> -#include <QtCore/qstack.h> -#include <QtCore/qstringlist.h> -#include <QtCore/QElapsedTimer> -#include <QtCore/QThreadStorage> - -#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/qdeclarativepropertycache_p.h> - -#include "qv8contextwrapper_p.h" -#include "qv8qobjectwrapper_p.h" -#include "qv8stringwrapper_p.h" -#include "qv8typewrapper_p.h" -#include "qv8listwrapper_p.h" -#include "qv8variantwrapper_p.h" -#include "qv8valuetypewrapper_p.h" -#include "qv8sequencewrapper_p.h" - -QT_BEGIN_NAMESPACE - - -// Uncomment the following line to enable global handle debugging. When enabled, all the persistent -// handles allocated using qPersistentNew() (or registered with qPersistentRegsiter()) and disposed -// with qPersistentDispose() are tracked. If you try and do something illegal, like double disposing -// a handle, qFatal() is called. -// #define QML_GLOBAL_HANDLE_DEBUGGING - -#define V8_RESOURCE_TYPE(resourcetype) \ -public: \ - enum { V8ResourceType = QV8ObjectResource:: resourcetype }; \ - virtual QV8ObjectResource::ResourceType resourceType() const { return QV8ObjectResource:: resourcetype; } \ -private: - -#define V8ENGINE() ((QV8Engine *)v8::External::Unwrap(args.Data())) -#define V8FUNCTION(function, engine) v8::FunctionTemplate::New(function, v8::External::Wrap((QV8Engine*)engine))->GetFunction() -#define V8THROW_ERROR(string) { \ - v8::ThrowException(v8::Exception::Error(v8::String::New(string))); \ - return v8::Handle<v8::Value>(); \ -} -#define V8THROW_TYPE(string) { \ - v8::ThrowException(v8::Exception::TypeError(v8::String::New(string))); \ - return v8::Handle<v8::Value>(); \ -} -#define V8ENGINE_ACCESSOR() ((QV8Engine *)v8::External::Unwrap(info.Data())); -#define V8THROW_ERROR_SETTER(string) { \ - v8::ThrowException(v8::Exception::Error(v8::String::New(string))); \ - return; \ -} - -#define V8_DEFINE_EXTENSION(dataclass, datafunction) \ - static inline dataclass *datafunction(QV8Engine *engine) \ - { \ - static int extensionId = -1; \ - if (extensionId == -1) { \ - QV8Engine::registrationMutex()->lock(); \ - if (extensionId == -1) \ - extensionId = QV8Engine::registerExtension(); \ - QV8Engine::registrationMutex()->unlock(); \ - } \ - dataclass *rv = (dataclass *)engine->extensionData(extensionId); \ - if (!rv) { \ - rv = new dataclass(engine); \ - engine->setExtensionData(extensionId, rv); \ - } \ - return rv; \ - } \ - - -class QV8Engine; -class QV8ObjectResource : public v8::Object::ExternalResource -{ -public: - QV8ObjectResource(QV8Engine *engine) : engine(engine) { Q_ASSERT(engine); } - enum ResourceType { ContextType, QObjectType, TypeType, ListType, VariantType, - ValueTypeType, XMLHttpRequestType, DOMNodeType, SQLDatabaseType, - ListModelType, Context2DType, Context2DStyleType, Context2DPixelArrayType, - ParticleDataType, SignalHandlerType, IncubatorType, VisualDataItemType, - SequenceType, LocaleDataType }; - virtual ResourceType resourceType() const = 0; - - QV8Engine *engine; -}; - -template<class T> -inline T *v8_resource_cast(v8::Handle<v8::Object> object) { - QV8ObjectResource *resource = static_cast<QV8ObjectResource *>(object->GetExternalResource()); - return (resource && (quint32)resource->resourceType() == (quint32)T::V8ResourceType)?static_cast<T *>(resource):0; -} - -template<class T> -inline T *v8_resource_check(v8::Handle<v8::Object> object) { - T *resource = static_cast<T *>(object->GetExternalResource()); - Q_ASSERT(resource && resource->resourceType() == (quint32)T::V8ResourceType); - return resource; -} - -// Used to allow a QObject method take and return raw V8 handles without having to expose -// v8 in the public API. -// Use like this: -// class MyClass : public QObject { -// Q_OBJECT -// ... -// Q_INVOKABLE void myMethod(QDeclarativeV8Function*); -// }; -// The QDeclarativeV8Function - and consequently the arguments and return value - only remains -// valid during the call. If the return value isn't set within myMethod(), the will return -// undefined. -class QV8Engine; -class QDeclarativeV8Function -{ -public: - int Length() const { return _ac; } - v8::Local<v8::Value> operator[](int idx) { return (*_a)->Get(idx); } - QDeclarativeContextData *context() { return _c; } - v8::Handle<v8::Object> qmlGlobal() { return *_g; } - void returnValue(v8::Handle<v8::Value> rv) { *_r = rv; } - QV8Engine *engine() const { return _e; } -private: - friend class QV8QObjectWrapper; - QDeclarativeV8Function(); - QDeclarativeV8Function(const QDeclarativeV8Function &); - QDeclarativeV8Function &operator=(const QDeclarativeV8Function &); - - QDeclarativeV8Function(int length, v8::Handle<v8::Object> &args, - v8::Handle<v8::Value> &rv, v8::Handle<v8::Object> &global, - QDeclarativeContextData *c, QV8Engine *e) - : _ac(length), _a(&args), _r(&rv), _g(&global), _c(c), _e(e) {} - - int _ac; - v8::Handle<v8::Object> *_a; - v8::Handle<v8::Value> *_r; - v8::Handle<v8::Object> *_g; - QDeclarativeContextData *_c; - QV8Engine *_e; -}; - -class QDeclarativeV8Handle -{ -public: - QDeclarativeV8Handle() : d(0) {} - QDeclarativeV8Handle(const QDeclarativeV8Handle &other) : d(other.d) {} - QDeclarativeV8Handle &operator=(const QDeclarativeV8Handle &other) { d = other.d; return *this; } - - static QDeclarativeV8Handle fromHandle(v8::Handle<v8::Value> h) { - return QDeclarativeV8Handle(*h); - } - v8::Handle<v8::Value> toHandle() const { - return v8::Handle<v8::Value>((v8::Value *)d); - } -private: - QDeclarativeV8Handle(void *d) : d(d) {} - void *d; -}; - -class QObject; -class QDeclarativeEngine; -class QDeclarativeValueType; -class QNetworkAccessManager; -class QDeclarativeContextData; - -class Q_AUTOTEST_EXPORT QV8GCCallback -{ -private: - class ThreadData; -public: - static void garbageCollectorPrologueCallback(v8::GCType, v8::GCCallbackFlags); - static void registerGcPrologueCallback(); - - class Q_AUTOTEST_EXPORT Node { - public: - typedef void (*PrologueCallback)(Node *node); - Node(PrologueCallback callback); - ~Node(); - - QIntrusiveListNode node; - PrologueCallback prologueCallback; - }; - - static void addGcCallbackNode(Node *node); -}; - -class Q_DECLARATIVE_EXPORT QV8Engine -{ -public: - static QV8Engine* get(QJSEngine* q) { Q_ASSERT(q); return q->handle(); } - static QJSEngine* get(QV8Engine* d) { Q_ASSERT(d); return d->q; } - - QV8Engine(QJSEngine* qq,QJSEngine::ContextOwnership ownership = QJSEngine::CreateNewContext); - virtual ~QV8Engine(); - - // This enum should be in sync with QDeclarativeEngine::ObjectOwnership - enum ObjectOwnership { CppOwnership, JavaScriptOwnership }; - - struct Deletable { - virtual ~Deletable() {} - }; - - class Exception - { - typedef QPair<v8::Persistent<v8::Value>, v8::Persistent<v8::Message> > ValueMessagePair; - - v8::Persistent<v8::Value> m_value; - v8::Persistent<v8::Message> m_message; - QStack<ValueMessagePair> m_stack; - - Q_DISABLE_COPY(Exception) - public: - inline Exception(); - inline ~Exception(); - inline void set(v8::Handle<v8::Value> value, v8::Handle<v8::Message> message); - inline void clear(); - inline operator bool() const; - inline operator v8::Handle<v8::Value>() const; - inline int lineNumber() const; - inline QStringList backtrace() const; - - inline void push(); - inline void pop(); - }; - - void initDeclarativeGlobalObject(); - void setEngine(QDeclarativeEngine *engine); - QDeclarativeEngine *engine() { return m_engine; } - 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 registerValueIterator(QJSValueIteratorPrivate *data); - inline void unregisterValueIterator(QJSValueIteratorPrivate *data); - inline void invalidateAllIterators(); - - QV8ContextWrapper *contextWrapper() { return &m_contextWrapper; } - QV8QObjectWrapper *qobjectWrapper() { return &m_qobjectWrapper; } - QV8TypeWrapper *typeWrapper() { return &m_typeWrapper; } - QV8ListWrapper *listWrapper() { return &m_listWrapper; } - QV8VariantWrapper *variantWrapper() { return &m_variantWrapper; } - QV8ValueTypeWrapper *valueTypeWrapper() { return &m_valueTypeWrapper; } - QV8SequenceWrapper *sequenceWrapper() { return &m_sequenceWrapper; } - - void *xmlHttpRequestData() { return m_xmlHttpRequestData; } - - Deletable *listModelData() { return m_listModelData; } - void setListModelData(Deletable *d) { if (m_listModelData) delete m_listModelData; m_listModelData = d; } - - QDeclarativeContextData *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); - inline QString toString(v8::Handle<v8::String> string); - static QString toStringStatic(v8::Handle<v8::Value>); - static QString toStringStatic(v8::Handle<v8::String>); - static inline bool startsWithUpper(v8::Handle<v8::String>); - - QVariant toVariant(v8::Handle<v8::Value>, int typeHint); - v8::Handle<v8::Value> fromVariant(const QVariant &); - inline bool isVariant(v8::Handle<v8::Value>); - - // Compile \a source (from \a fileName at \a lineNumber) in QML mode - v8::Local<v8::Script> qmlModeCompile(const QString &source, - const QString &fileName = QString(), - int lineNumber = 1); - v8::Local<v8::Script> qmlModeCompile(const char *source, int sourceLength = -1, - const QString &fileName = QString(), - int lineNumber = 1); - - // Return the QML global "scope" object for the \a ctxt context and \a scope object. - inline v8::Local<v8::Object> qmlScope(QDeclarativeContextData *ctxt, QObject *scope); - - // Return a JS wrapper for the given QObject \a object - inline v8::Handle<v8::Value> newQObject(QObject *object); - inline v8::Handle<v8::Value> newQObject(QObject *object, const ObjectOwnership ownership); - inline bool isQObject(v8::Handle<v8::Value>); - inline QObject *toQObject(v8::Handle<v8::Value>); - - // Return a JS string for the given QString \a string - inline v8::Local<v8::String> toString(const QString &string); - - // Create a new value type object - inline v8::Handle<v8::Value> newValueType(QObject *, int coreIndex, QDeclarativeValueType *); - inline v8::Handle<v8::Value> newValueType(const QVariant &, QDeclarativeValueType *); - - // Create a new sequence type object - inline v8::Handle<v8::Value> newSequence(int sequenceType, QObject *, int coreIndex, bool *succeeded); - - // Create a new QVariant object. This doesn't examine the type of the variant, but always returns - // a QVariant wrapper - inline v8::Handle<v8::Value> newQVariant(const QVariant &); - - // Return the network access manager for this engine. By default this returns the network - // access manager of the QDeclarativeEngine. It is overridden in the case of a threaded v8 - // instance (like in WorkerScript). - virtual QNetworkAccessManager *networkAccessManager(); - - // Return the list of illegal id names (the names of the properties on the global object) - const QStringHash<bool> &illegalNames() const; - - inline void collectGarbage() { gc(); } - static void gc(); - - void clearExceptions(); - void setException(v8::Handle<v8::Value> value, v8::Handle<v8::Message> message = v8::Handle<v8::Message>()); - v8::Handle<v8::Value> throwException(v8::Handle<v8::Value> value); - bool hasUncaughtException() const; - int uncaughtExceptionLineNumber() const; - QStringList uncaughtExceptionBacktrace() const; - v8::Handle<v8::Value> uncaughtException() const; - void saveException(); - void restoreException(); - -#ifdef QML_GLOBAL_HANDLE_DEBUGGING - // Used for handle debugging - static void registerHandle(void *); - static void releaseHandle(void *); -#endif - - static QMutex *registrationMutex(); - static int registerExtension(); - - 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); - - inline QScriptPassPointer<QJSValuePrivate> evaluate(const QString &program, const QString &fileName = QString(), int lineNumber = 1); - QScriptPassPointer<QJSValuePrivate> evaluate(v8::Handle<v8::Script> script, v8::TryCatch& tryCatch); - - QScriptPassPointer<QJSValuePrivate> newArray(uint length); - v8::Local<v8::Object> newVariant(const QVariant &variant); - - v8::Local<v8::Array> variantListToJS(const QVariantList &lst); - QVariantList variantListFromJS(v8::Handle<v8::Array> jsArray); - - v8::Local<v8::Object> variantMapToJS(const QVariantMap &vmap); - QVariantMap variantMapFromJS(v8::Handle<v8::Object> jsObject); - - v8::Handle<v8::Value> variantToJS(const QVariant &value); - QVariant variantFromJS(v8::Handle<v8::Value> value); - - v8::Handle<v8::Value> metaTypeToJS(int type, const void *data); - bool metaTypeFromJS(v8::Handle<v8::Value> value, int type, void *data); - - bool convertToNativeQObject(v8::Handle<v8::Value> value, - const QByteArray &targetType, - void **result); - - QVariant &variantValue(v8::Handle<v8::Value> value); - - QJSValue scriptValueFromInternal(v8::Handle<v8::Value>) const; - - void emitSignalHandlerException(); - - // used for console.time(), console.timeEnd() - void startTimer(const QString &timerName); - qint64 stopTimer(const QString &timerName, bool *wasRunning); - - // used for console.count() - int consoleCountHelper(const QString &file, int line, int column); - - QObject *qtObjectFromJS(v8::Handle<v8::Value> value); - QSet<int> visitedConversionObjects; - - static QDateTime qtDateTimeFromJsDate(double jsDate); - - void addRelationshipForGC(QObject *object, v8::Persistent<v8::Value> handle); - void addRelationshipForGC(QObject *object, QObject *other); - - struct ThreadData { - ThreadData(); - ~ThreadData(); - v8::Isolate* isolate; - bool gcPrologueCallbackRegistered; - QIntrusiveList<QV8GCCallback::Node, &QV8GCCallback::Node::node> gcCallbackNodes; - }; - - static bool hasThreadData(); - static ThreadData* threadData(); - static void ensurePerThreadIsolate(); - - v8::Persistent<v8::Object> m_strongReferencer; - -protected: - QJSEngine* q; - QDeclarativeEngine *m_engine; - bool m_ownsV8Context; - v8::Persistent<v8::Context> m_context; - QScriptOriginalGlobalObject m_originalGlobalObject; - - QV8StringWrapper m_stringWrapper; - QV8ContextWrapper m_contextWrapper; - QV8QObjectWrapper m_qobjectWrapper; - QV8TypeWrapper m_typeWrapper; - QV8ListWrapper m_listWrapper; - QV8VariantWrapper m_variantWrapper; - QV8ValueTypeWrapper m_valueTypeWrapper; - QV8SequenceWrapper m_sequenceWrapper; - - v8::Persistent<v8::Function> m_getOwnPropertyNames; - v8::Persistent<v8::Function> m_freezeObject; - - void *m_xmlHttpRequestData; - - QVector<Deletable *> m_extensionData; - Deletable *m_listModelData; - - QStringHash<bool> m_illegalNames; - - Exception m_exception; - - QElapsedTimer m_time; - QHash<QString, qint64> m_startedTimers; - - QHash<QString, quint32> m_consoleCount; - - QVariant toBasicVariant(v8::Handle<v8::Value>); - - void initializeGlobal(v8::Handle<v8::Object>); - - double qtDateTimeToJsDate(const QDateTime &dt); - -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; - - Q_DISABLE_COPY(QV8Engine) -}; - -// Allocate a new Persistent handle. *ALL* persistent handles in QML must be allocated -// using this method. -template<class T> -v8::Persistent<T> qPersistentNew(v8::Handle<T> that) -{ - v8::Persistent<T> rv = v8::Persistent<T>::New(that); -#ifdef QML_GLOBAL_HANDLE_DEBUGGING - QV8Engine::registerHandle(*rv); -#endif - return rv; -} - -// Register a Persistent handle that was returned to you by V8 (such as by -// v8::Context::New). This allows us to do handle tracking on these handles too. -template<class T> -void qPersistentRegister(v8::Persistent<T> handle) -{ -#ifdef QML_GLOBAL_HANDLE_DEBUGGING - QV8Engine::registerHandle(*handle); -#else - Q_UNUSED(handle); -#endif -} - -// Dispose and clear a persistent handle. *ALL* persistent handles in QML must be -// disposed using this method. -template<class T> -void qPersistentDispose(v8::Persistent<T> &that) -{ -#ifdef QML_GLOBAL_HANDLE_DEBUGGING - QV8Engine::releaseHandle(*that); -#endif - that.Dispose(); - that.Clear(); -} - -QString QV8Engine::toString(v8::Handle<v8::Value> string) -{ - return m_stringWrapper.toString(string->ToString()); -} - -QString QV8Engine::toString(v8::Handle<v8::String> string) -{ - return m_stringWrapper.toString(string); -} - -bool QV8Engine::isVariant(v8::Handle<v8::Value> value) -{ - return m_variantWrapper.isVariant(value); -} - -v8::Local<v8::Object> QV8Engine::qmlScope(QDeclarativeContextData *ctxt, QObject *scope) -{ - return m_contextWrapper.qmlScope(ctxt, scope); -} - -bool QV8Engine::isQObject(v8::Handle<v8::Value> obj) -{ - return obj->IsObject()?m_qobjectWrapper.isQObject(v8::Handle<v8::Object>::Cast(obj)):false; -} - -QObject *QV8Engine::toQObject(v8::Handle<v8::Value> obj) -{ - return obj->IsObject()?m_qobjectWrapper.toQObject(v8::Handle<v8::Object>::Cast(obj)):0; -} - -v8::Handle<v8::Value> QV8Engine::newQObject(QObject *object) -{ - return m_qobjectWrapper.newQObject(object); -} - -v8::Handle<v8::Value> QV8Engine::newQObject(QObject *object, const ObjectOwnership ownership) -{ - if (!object) - return v8::Null(); - - v8::Handle<v8::Value> result = newQObject(object); - QDeclarativeData *ddata = QDeclarativeData::get(object, true); - if (ownership == JavaScriptOwnership && ddata) { - ddata->indestructible = false; - ddata->explicitIndestructibleSet = true; - } - return result; -} - -v8::Local<v8::String> QV8Engine::toString(const QString &string) -{ - return m_stringWrapper.toString(string); -} - -v8::Handle<v8::Value> QV8Engine::newValueType(QObject *object, int property, QDeclarativeValueType *type) -{ - return m_valueTypeWrapper.newValueType(object, property, type); -} - -v8::Handle<v8::Value> QV8Engine::newValueType(const QVariant &value, QDeclarativeValueType *type) -{ - return m_valueTypeWrapper.newValueType(value, type); -} - -v8::Handle<v8::Value> QV8Engine::newSequence(int sequenceType, QObject *object, int property, bool *succeeded) -{ - return m_sequenceWrapper.newSequence(sequenceType, object, property, succeeded); -} - -// XXX Can this be made more optimal? It is called prior to resolving each and every -// unqualified name in QV8ContextWrapper. -bool QV8Engine::startsWithUpper(v8::Handle<v8::String> string) -{ - uint16_t c = string->GetCharacter(0); - return (c >= 'A' && c <= 'Z') || - (c > 127 && QChar::category(c) == QChar::Letter_Uppercase); -} - -QV8Engine::Deletable *QV8Engine::extensionData(int index) const -{ - if (index < m_extensionData.count()) - return m_extensionData[index]; - else - return 0; -} - -QT_END_NAMESPACE - -#endif // QDECLARATIVEV8ENGINE_P_H diff --git a/src/declarative/qml/v8/qv8include.cpp b/src/declarative/qml/v8/qv8include.cpp deleted file mode 100644 index 116baee0e2..0000000000 --- a/src/declarative/qml/v8/qv8include.cpp +++ /dev/null @@ -1,244 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qv8include_p.h" - -#include <QtDeclarative/qjsengine.h> -#include <QtNetwork/qnetworkrequest.h> -#include <QtNetwork/qnetworkreply.h> -#include <QtCore/qfile.h> - -#include <private/qdeclarativeengine_p.h> - -QT_BEGIN_NAMESPACE - -QV8Include::QV8Include(const QUrl &url, QV8Engine *engine, QDeclarativeContextData *context, - v8::Handle<v8::Object> qmlglobal, v8::Handle<v8::Function> callback) -: m_engine(engine), m_network(0), m_reply(0), m_url(url), m_redirectCount(0), m_context(context) -{ - m_qmlglobal = qPersistentNew<v8::Object>(qmlglobal); - if (!callback.IsEmpty()) - m_callbackFunction = qPersistentNew<v8::Function>(callback); - - m_resultObject = qPersistentNew<v8::Object>(resultValue()); - - m_network = engine->networkAccessManager(); - - QNetworkRequest request; - request.setUrl(url); - - m_reply = m_network->get(request); - QObject::connect(m_reply, SIGNAL(finished()), this, SLOT(finished())); -} - -QV8Include::~QV8Include() -{ - delete m_reply; m_reply = 0; - qPersistentDispose(m_callbackFunction); - qPersistentDispose(m_resultObject); -} - -v8::Local<v8::Object> QV8Include::resultValue(Status status) -{ - // XXX It seems inefficient to create this object from scratch each time. - v8::Local<v8::Object> result = v8::Object::New(); - result->Set(v8::String::New("OK"), v8::Integer::New(Ok)); - result->Set(v8::String::New("LOADING"), v8::Integer::New(Loading)); - result->Set(v8::String::New("NETWORK_ERROR"), v8::Integer::New(NetworkError)); - result->Set(v8::String::New("EXCEPTION"), v8::Integer::New(Exception)); - - result->Set(v8::String::New("status"), v8::Integer::New(status)); - - return result; -} - -void QV8Include::callback(QV8Engine *engine, v8::Handle<v8::Function> callback, v8::Handle<v8::Object> status) -{ - if (!callback.IsEmpty()) { - v8::Handle<v8::Value> args[] = { status }; - v8::TryCatch tc; - callback->Call(engine->global(), 1, args); - } -} - -v8::Handle<v8::Object> QV8Include::result() -{ - return m_resultObject; -} - -#define INCLUDE_MAXIMUM_REDIRECT_RECURSION 15 -void QV8Include::finished() -{ - m_redirectCount++; - - if (m_redirectCount < INCLUDE_MAXIMUM_REDIRECT_RECURSION) { - QVariant redirect = m_reply->attribute(QNetworkRequest::RedirectionTargetAttribute); - if (redirect.isValid()) { - m_url = m_url.resolved(redirect.toUrl()); - delete m_reply; - - QNetworkRequest request; - request.setUrl(m_url); - - m_reply = m_network->get(request); - QObject::connect(m_reply, SIGNAL(finished()), this, SLOT(finished())); - return; - } - } - - v8::HandleScope handle_scope; - - if (m_reply->error() == QNetworkReply::NoError) { - QByteArray data = m_reply->readAll(); - - QString code = QString::fromUtf8(data); - QDeclarativeScript::Parser::extractPragmas(code); - - QDeclarativeContextData *importContext = new QDeclarativeContextData; - importContext->isInternal = true; - importContext->isJSContext = true; - importContext->url = m_url; - importContext->isPragmaLibraryContext = m_context->isPragmaLibraryContext; - importContext->setParent(m_context, true); - - v8::Context::Scope ctxtscope(m_engine->context()); - v8::TryCatch try_catch; - - v8::Local<v8::Script> script = m_engine->qmlModeCompile(code, m_url.toString()); - - if (!try_catch.HasCaught()) { - m_engine->contextWrapper()->addSubContext(m_qmlglobal, script, importContext); - script->Run(m_qmlglobal); - } - - if (try_catch.HasCaught()) { - m_resultObject->Set(v8::String::New("status"), v8::Integer::New(Exception)); - m_resultObject->Set(v8::String::New("exception"), try_catch.Exception()); - } else { - m_resultObject->Set(v8::String::New("status"), v8::Integer::New(Ok)); - } - } else { - m_resultObject->Set(v8::String::New("status"), v8::Integer::New(NetworkError)); - } - - callback(m_engine, m_callbackFunction, m_resultObject); - - disconnect(); - deleteLater(); -} - -/* - Documented in qv8engine.cpp -*/ -v8::Handle<v8::Value> QV8Include::include(const v8::Arguments &args) -{ - if (args.Length() == 0) - return v8::Undefined(); - - QV8Engine *engine = V8ENGINE(); - QDeclarativeContextData *context = engine->callingContext(); - - if (!context || !context->isJSContext) - V8THROW_ERROR("Qt.include(): Can only be called from JavaScript files"); - - QUrl url(context->resolvedUrl(QUrl(engine->toString(args[0]->ToString())))); - - v8::Local<v8::Function> callbackFunction; - if (args.Length() >= 2 && args[1]->IsFunction()) - callbackFunction = v8::Local<v8::Function>::Cast(args[1]); - - QString localFile = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(url); - - v8::Local<v8::Object> result; - - if (localFile.isEmpty()) { - - QV8Include *i = new QV8Include(url, engine, context, - v8::Context::GetCallingQmlGlobal(), - callbackFunction); - result = v8::Local<v8::Object>::New(i->result()); - - } else { - - QFile f(localFile); - - if (f.open(QIODevice::ReadOnly)) { - QByteArray data = f.readAll(); - QString code = QString::fromUtf8(data); - QDeclarativeScript::Parser::extractPragmas(code); - - QDeclarativeContextData *importContext = new QDeclarativeContextData; - importContext->isInternal = true; - importContext->isJSContext = true; - importContext->url = url; - importContext->setParent(context, true); - - v8::TryCatch try_catch; - - v8::Local<v8::Script> script = engine->qmlModeCompile(code, url.toString()); - - if (!try_catch.HasCaught()) { - v8::Local<v8::Object> qmlglobal = v8::Context::GetCallingQmlGlobal(); - engine->contextWrapper()->addSubContext(qmlglobal, script, importContext); - script->Run(qmlglobal); - } - - if (try_catch.HasCaught()) { - result = resultValue(Exception); - result->Set(v8::String::New("exception"), try_catch.Exception()); - } else { - result = resultValue(Ok); - } - - } else { - result = resultValue(NetworkError); - } - - callback(engine, callbackFunction, result); - } - - if (result.IsEmpty()) - return v8::Undefined(); - else - return result; -} - -QT_END_NAMESPACE diff --git a/src/declarative/qml/v8/qv8include_p.h b/src/declarative/qml/v8/qv8include_p.h deleted file mode 100644 index 89ff2967ed..0000000000 --- a/src/declarative/qml/v8/qv8include_p.h +++ /dev/null @@ -1,113 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QV8INCLUDE_P_H -#define QV8INCLUDE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/qobject.h> -#include <QtCore/qurl.h> - -#include <private/qdeclarativecontext_p.h> -#include <private/qdeclarativeguard_p.h> - -#include <private/qv8_p.h> - -QT_BEGIN_NAMESPACE - -class QDeclarativeEngine; -class QNetworkAccessManager; -class QNetworkReply; -class QV8Engine; -class QV8Include : public QObject -{ - Q_OBJECT -public: - enum Status { - Ok = 0, - Loading = 1, - NetworkError = 2, - Exception = 3 - }; - - static v8::Handle<v8::Value> include(const v8::Arguments &args); - -private slots: - void finished(); - -private: - QV8Include(const QUrl &, QV8Engine *, QDeclarativeContextData *, - v8::Handle<v8::Object>, v8::Handle<v8::Function>); - ~QV8Include(); - - v8::Handle<v8::Object> result(); - - static v8::Local<v8::Object> resultValue(Status status = Loading); - static void callback(QV8Engine *engine, v8::Handle<v8::Function> callback, v8::Handle<v8::Object> status); - - QV8Engine *m_engine; - QNetworkAccessManager *m_network; - QDeclarativeGuard<QNetworkReply> m_reply; - - QUrl m_url; - int m_redirectCount; - - v8::Persistent<v8::Function> m_callbackFunction; - v8::Persistent<v8::Object> m_resultObject; - - QDeclarativeGuardedContextData m_context; - v8::Persistent<v8::Object> m_qmlglobal; -}; - -QT_END_NAMESPACE - -#endif // QV8INCLUDE_P_H - diff --git a/src/declarative/qml/v8/qv8listwrapper.cpp b/src/declarative/qml/v8/qv8listwrapper.cpp deleted file mode 100644 index 08b548aa08..0000000000 --- a/src/declarative/qml/v8/qv8listwrapper.cpp +++ /dev/null @@ -1,194 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qv8listwrapper_p.h" -#include "qv8engine_p.h" -#include <private/qdeclarativelist_p.h> - -QT_BEGIN_NAMESPACE - -class QV8ListResource : public QV8ObjectResource -{ - V8_RESOURCE_TYPE(ListType); -public: - QV8ListResource(QV8Engine *engine) : QV8ObjectResource(engine) {} - - QDeclarativeGuard<QObject> object; - QDeclarativeListProperty<QObject> property; - int propertyType; -}; - -QV8ListWrapper::QV8ListWrapper() -: m_engine(0) -{ -} - -QV8ListWrapper::~QV8ListWrapper() -{ -} - -void QV8ListWrapper::init(QV8Engine *engine) -{ - m_engine = engine; - v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New(); - ft->InstanceTemplate()->SetFallbackPropertyHandler(Getter, Setter, 0, 0, Enumerator); - ft->InstanceTemplate()->SetIndexedPropertyHandler(IndexedGetter); - ft->InstanceTemplate()->SetAccessor(v8::String::New("length"), LengthGetter, 0, - v8::Handle<v8::Value>(), v8::DEFAULT, - v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete | v8::DontEnum)); - ft->InstanceTemplate()->SetHasExternalResource(true); - m_constructor = qPersistentNew<v8::Function>(ft->GetFunction()); -} - -void QV8ListWrapper::destroy() -{ - qPersistentDispose(m_constructor); -} - -v8::Handle<v8::Value> QV8ListWrapper::newList(QObject *object, int propId, int propType) -{ - if (!object || propId == -1) - return v8::Null(); - - // XXX NewInstance() should be optimized - v8::Local<v8::Object> rv = m_constructor->NewInstance(); - QV8ListResource *r = new QV8ListResource(m_engine); - r->object = object; - r->propertyType = propType; - void *args[] = { &r->property, 0 }; - QMetaObject::metacall(object, QMetaObject::ReadProperty, propId, args); - rv->SetExternalResource(r); - return rv; -} - -v8::Handle<v8::Value> QV8ListWrapper::newList(const QDeclarativeListProperty<QObject> &prop, int propType) -{ - // XXX NewInstance() should be optimized - v8::Local<v8::Object> rv = m_constructor->NewInstance(); - QV8ListResource *r = new QV8ListResource(m_engine); - r->object = prop.object; - r->property = prop; - r->propertyType = propType; - rv->SetExternalResource(r); - return rv; -} - -QVariant QV8ListWrapper::toVariant(v8::Handle<v8::Object> obj) -{ - QV8ListResource *resource = v8_resource_cast<QV8ListResource>(obj); - if (resource) return toVariant(resource); - else return QVariant(); -} - -QVariant QV8ListWrapper::toVariant(QV8ObjectResource *r) -{ - Q_ASSERT(r->resourceType() == QV8ObjectResource::ListType); - QV8ListResource *resource = static_cast<QV8ListResource *>(r); - - if (!resource->object) - return QVariant(); - - return QVariant::fromValue(QDeclarativeListReferencePrivate::init(resource->property, resource->propertyType, - m_engine->engine())); -} - -v8::Handle<v8::Value> QV8ListWrapper::Getter(v8::Local<v8::String> property, - const v8::AccessorInfo &info) -{ - Q_UNUSED(property); - Q_UNUSED(info); - return v8::Handle<v8::Value>(); -} - -v8::Handle<v8::Value> QV8ListWrapper::Setter(v8::Local<v8::String> property, - v8::Local<v8::Value> value, - const v8::AccessorInfo &info) -{ - Q_UNUSED(property); - Q_UNUSED(info); - return value; -} - -v8::Handle<v8::Value> QV8ListWrapper::IndexedGetter(uint32_t index, const v8::AccessorInfo &info) -{ - QV8ListResource *resource = v8_resource_cast<QV8ListResource>(info.This()); - - if (!resource || resource->object.isNull()) return v8::Undefined(); - - quint32 count = resource->property.count?resource->property.count(&resource->property):0; - if (index < count && resource->property.at) { - return resource->engine->newQObject(resource->property.at(&resource->property, index)); - } else { - return v8::Undefined(); - } -} - -v8::Handle<v8::Value> QV8ListWrapper::LengthGetter(v8::Local<v8::String> property, - const v8::AccessorInfo &info) -{ - Q_UNUSED(property); - - QV8ListResource *resource = v8_resource_cast<QV8ListResource>(info.This()); - - if (!resource || resource->object.isNull()) return v8::Undefined(); - - quint32 count = resource->property.count?resource->property.count(&resource->property):0; - - return v8::Integer::NewFromUnsigned(count); -} - -v8::Handle<v8::Array> QV8ListWrapper::Enumerator(const v8::AccessorInfo &info) -{ - QV8ListResource *resource = v8_resource_cast<QV8ListResource>(info.This()); - - if (!resource || resource->object.isNull()) return v8::Array::New(); - - quint32 count = resource->property.count?resource->property.count(&resource->property):0; - - v8::Local<v8::Array> rv = v8::Array::New(count); - - for (uint ii = 0; ii < count; ++ii) - rv->Set(ii, v8::Number::New(ii)); - - return rv; -} - -QT_END_NAMESPACE diff --git a/src/declarative/qml/v8/qv8listwrapper_p.h b/src/declarative/qml/v8/qv8listwrapper_p.h deleted file mode 100644 index 891e84de65..0000000000 --- a/src/declarative/qml/v8/qv8listwrapper_p.h +++ /dev/null @@ -1,97 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QV8LISTWRAPPER_P_H -#define QV8LISTWRAPPER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/qglobal.h> -#include <QtDeclarative/qdeclarativelist.h> -#include <private/qv8_p.h> - -QT_BEGIN_NAMESPACE - -class QV8Engine; -class QV8ObjectResource; -class QV8ListWrapper -{ -public: - QV8ListWrapper(); - ~QV8ListWrapper(); - - void init(QV8Engine *); - void destroy(); - - v8::Handle<v8::Value> newList(QObject *, int, int); - v8::Handle<v8::Value> newList(const QDeclarativeListProperty<QObject> &, int); - QVariant toVariant(v8::Handle<v8::Object>); - QVariant toVariant(QV8ObjectResource *); - -private: - static v8::Handle<v8::Value> Getter(v8::Local<v8::String> property, - const v8::AccessorInfo &info); - static v8::Handle<v8::Value> Setter(v8::Local<v8::String> property, - v8::Local<v8::Value> value, - const v8::AccessorInfo &info); - static v8::Handle<v8::Value> IndexedGetter(uint32_t index, - const v8::AccessorInfo &info); - static v8::Handle<v8::Value> LengthGetter(v8::Local<v8::String> property, - const v8::AccessorInfo &info); - static v8::Handle<v8::Array> Enumerator(const v8::AccessorInfo &info); - - QV8Engine *m_engine; - v8::Persistent<v8::Function> m_constructor; -}; - -QT_END_NAMESPACE - -#endif // QV8LISTWRAPPER_P_H - diff --git a/src/declarative/qml/v8/qv8profiler_p.h b/src/declarative/qml/v8/qv8profiler_p.h deleted file mode 100644 index 4aba9ecdb5..0000000000 --- a/src/declarative/qml/v8/qv8profiler_p.h +++ /dev/null @@ -1,42 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <private/v8-profiler.h> diff --git a/src/declarative/qml/v8/qv8qobjectwrapper.cpp b/src/declarative/qml/v8/qv8qobjectwrapper.cpp deleted file mode 100644 index 11733be5fd..0000000000 --- a/src/declarative/qml/v8/qv8qobjectwrapper.cpp +++ /dev/null @@ -1,2113 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qv8qobjectwrapper_p.h" -#include "qv8contextwrapper_p.h" -#include "qv8engine_p.h" - -#include <private/qdeclarativeguard_p.h> -#include <private/qdeclarativepropertycache_p.h> -#include <private/qdeclarativeengine_p.h> -#include <private/qdeclarativevmemetaobject_p.h> -#include <private/qdeclarativebinding_p.h> -#include <private/qjsvalue_p.h> -#include <private/qscript_impl_p.h> -#include <private/qdeclarativeaccessors_p.h> -#include <private/qdeclarativeexpression_p.h> - -#include <QtDeclarative/qjsvalue.h> -#include <QtCore/qvarlengtharray.h> -#include <QtCore/qtimer.h> -#include <QtCore/qatomic.h> - -Q_DECLARE_METATYPE(QJSValue); -Q_DECLARE_METATYPE(QDeclarativeV8Handle); - -QT_BEGIN_NAMESPACE - -#if defined(__GNUC__) -# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 405 -// The code in this file does not violate strict aliasing, but GCC thinks it does -// so turn off the warnings for us to have a clean build -# pragma GCC diagnostic ignored "-Wstrict-aliasing" -# endif -#endif - -#define QOBJECT_TOSTRING_INDEX -2 -#define QOBJECT_DESTROY_INDEX -3 - -// XXX TODO: Need to review all calls to QDeclarativeEngine *engine() to confirm QObjects work -// correctly in a worker thread - -class QV8QObjectResource : public QV8ObjectResource -{ - V8_RESOURCE_TYPE(QObjectType); - -public: - QV8QObjectResource(QV8Engine *engine, QObject *object); - - QDeclarativeGuard<QObject> object; -}; - -class QV8QObjectInstance : public QDeclarativeGuard<QObject> -{ -public: - QV8QObjectInstance(QObject *o, QV8QObjectWrapper *w) - : QDeclarativeGuard<QObject>(o), wrapper(w) - { - } - - ~QV8QObjectInstance() - { - qPersistentDispose(v8object); - } - - virtual void objectDestroyed(QObject *o) - { - if (wrapper) - wrapper->m_taintedObjects.remove(o); - delete this; - } - - v8::Persistent<v8::Object> v8object; - QV8QObjectWrapper *wrapper; -}; - -class QV8SignalHandlerResource : public QV8ObjectResource -{ - V8_RESOURCE_TYPE(SignalHandlerType) -public: - QV8SignalHandlerResource(QV8Engine *engine, QObject *object, int index); - - QDeclarativeGuard<QObject> object; - int index; -}; - -namespace { - -template<typename A, typename B, typename C, typename D, typename E> -class MaxSizeOf5 { - template<typename Z, typename X> - struct SMax { - static const size_t Size = sizeof(Z) > sizeof(X) ? sizeof(Z) : sizeof(X); - }; -public: - static const size_t Size = SMax<A, SMax<B, SMax<C, SMax<D, E> > > >::Size; -}; - -struct CallArgument { - inline CallArgument(); - inline ~CallArgument(); - inline void *dataPtr(); - - inline void initAsType(int type); - inline void fromValue(int type, QV8Engine *, v8::Handle<v8::Value>); - inline v8::Handle<v8::Value> toValue(QV8Engine *); - -private: - CallArgument(const CallArgument &); - - inline void cleanup(); - - union { - float floatValue; - double doubleValue; - quint32 intValue; - bool boolValue; - QObject *qobjectPtr; - - char allocData[MaxSizeOf5<QVariant, - QString, - QList<QObject *>, - QJSValue, - QDeclarativeV8Handle>::Size]; - qint64 q_for_alignment; - }; - - // Pointers to allocData - union { - QString *qstringPtr; - QVariant *qvariantPtr; - QList<QObject *> *qlistPtr; - QJSValue *qjsValuePtr; - QDeclarativeV8Handle *handlePtr; - }; - - int type; -}; -} - -QV8QObjectResource::QV8QObjectResource(QV8Engine *engine, QObject *object) -: QV8ObjectResource(engine), object(object) -{ -} - -QV8SignalHandlerResource::QV8SignalHandlerResource(QV8Engine *engine, QObject *object, int index) -: QV8ObjectResource(engine), object(object), index(index) -{ -} - -static QAtomicInt objectIdCounter(1); - -QV8QObjectWrapper::QV8QObjectWrapper() -: m_engine(0), m_id(objectIdCounter.fetchAndAddOrdered(1)) -{ -} - -QV8QObjectWrapper::~QV8QObjectWrapper() -{ - for (TaintedHash::Iterator iter = m_taintedObjects.begin(); - iter != m_taintedObjects.end(); - ++iter) { - (*iter)->wrapper = 0; - } - m_taintedObjects.clear(); -} - -void QV8QObjectWrapper::destroy() -{ - qDeleteAll(m_connections); - m_connections.clear(); - - qPersistentDispose(m_hiddenObject); - qPersistentDispose(m_destroySymbol); - qPersistentDispose(m_toStringSymbol); - qPersistentDispose(m_signalHandlerConstructor); - qPersistentDispose(m_methodConstructor); - qPersistentDispose(m_constructor); -} - -struct ReadAccessor { - static inline void Indirect(QObject *object, const QDeclarativePropertyData &property, - void *output, QDeclarativeNotifier **n) - { - Q_ASSERT(n == 0); - Q_UNUSED(n); - - void *args[] = { output, 0 }; - QMetaObject::metacall(object, QMetaObject::ReadProperty, property.coreIndex, args); - } - - static inline void Direct(QObject *object, const QDeclarativePropertyData &property, - void *output, QDeclarativeNotifier **n) - { - Q_ASSERT(n == 0); - Q_UNUSED(n); - - void *args[] = { output, 0 }; - object->qt_metacall(QMetaObject::ReadProperty, property.coreIndex, args); - } - - static inline void Accessor(QObject *object, const QDeclarativePropertyData &property, - void *output, QDeclarativeNotifier **n) - { - Q_ASSERT(property.accessors); - - property.accessors->read(object, property.accessorData, output); - if (n) property.accessors->notifier(object, property.accessorData, n); - } -}; - -static inline v8::Handle<v8::Value> valueToHandle(QV8Engine *, int v) -{ return v8::Integer::New(v); } -static inline v8::Handle<v8::Value> valueToHandle(QV8Engine *, uint v) -{ return v8::Integer::NewFromUnsigned(v); } -static inline v8::Handle<v8::Value> valueToHandle(QV8Engine *, bool v) -{ return v8::Boolean::New(v); } -static inline v8::Handle<v8::Value> valueToHandle(QV8Engine *e, const QString &v) -{ return e->toString(v); } -static inline v8::Handle<v8::Value> valueToHandle(QV8Engine *, float v) -{ return v8::Number::New(v); } -static inline v8::Handle<v8::Value> valueToHandle(QV8Engine *, double v) -{ return v8::Number::New(v); } -static inline v8::Handle<v8::Value> valueToHandle(QV8Engine *e, QObject *v) -{ return e->newQObject(v); } - -template<typename T, void (*ReadFunction)(QObject *, const QDeclarativePropertyData &, - void *, QDeclarativeNotifier **)> -static v8::Handle<v8::Value> GenericValueGetter(v8::Local<v8::String>, const v8::AccessorInfo &info) -{ - v8::Handle<v8::Object> This = info.This(); - QV8QObjectResource *resource = v8_resource_check<QV8QObjectResource>(This); - - QObject *object = resource->object; - if (!object) return v8::Undefined(); - - QDeclarativePropertyData *property = - (QDeclarativePropertyData *)v8::External::Unwrap(info.Data()); - - QDeclarativeEngine *engine = resource->engine->engine(); - QDeclarativeEnginePrivate *ep = engine?QDeclarativeEnginePrivate::get(engine):0; - - T value = T(); - - if (ep && ep->propertyCapture) { - if (ReadFunction == ReadAccessor::Accessor && property->accessors->notifier) { - QDeclarativeNotifier *notifier = 0; - ReadFunction(object, *property, &value, ¬ifier); - if (notifier) ep->captureProperty(notifier); - } else if (!property->isConstant()) { - ep->captureProperty(object, property->coreIndex, property->notifyIndex); - ReadFunction(object, *property, &value, 0); - } else { - ReadFunction(object, *property, &value, 0); - } - } else { - ReadFunction(object, *property, &value, 0); - } - - return valueToHandle(resource->engine, value); -} - -#define FAST_GETTER_FUNCTION(property, cpptype) \ - (property->hasAccessors()?((v8::AccessorGetter)GenericValueGetter<cpptype, &ReadAccessor::Accessor>):(property->isDirect()?((v8::AccessorGetter)GenericValueGetter<cpptype, &ReadAccessor::Direct>):((v8::AccessorGetter)GenericValueGetter<cpptype, &ReadAccessor::Indirect>))) - -static quint32 toStringHash = -1; -static quint32 destroyHash = -1; - -void QV8QObjectWrapper::init(QV8Engine *engine) -{ - m_engine = engine; - - m_toStringSymbol = qPersistentNew<v8::String>(v8::String::NewSymbol("toString")); - m_destroySymbol = qPersistentNew<v8::String>(v8::String::NewSymbol("destroy")); - m_hiddenObject = qPersistentNew<v8::Object>(v8::Object::New()); - - m_toStringString = QHashedV8String(m_toStringSymbol); - m_destroyString = QHashedV8String(m_destroySymbol); - - toStringHash = m_toStringString.hash(); - destroyHash = m_destroyString.hash(); - - { - v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New(); - ft->InstanceTemplate()->SetFallbackPropertyHandler(Getter, Setter, Query, 0, Enumerator); - ft->InstanceTemplate()->SetHasExternalResource(true); - m_constructor = qPersistentNew<v8::Function>(ft->GetFunction()); - } - { - v8::ScriptOrigin origin(m_hiddenObject); // Hack to allow us to identify these functions -#define CREATE_FUNCTION_SOURCE \ - "(function(method) { "\ - "return (function(object, data, qmlglobal) { "\ - "return (function() { "\ - "return method(object, data, qmlglobal, arguments.length, arguments); "\ - "});"\ - "});"\ - "})" - v8::Local<v8::Script> script = v8::Script::New(v8::String::New(CREATE_FUNCTION_SOURCE), &origin, 0, - v8::Handle<v8::String>(), v8::Script::NativeMode); -#undef CREATE_FUNCTION_SOURCE - v8::Local<v8::Function> fn = v8::Local<v8::Function>::Cast(script->Run()); - v8::Handle<v8::Value> invokeFn = v8::FunctionTemplate::New(Invoke)->GetFunction(); - v8::Handle<v8::Value> args[] = { invokeFn }; - v8::Local<v8::Function> createFn = v8::Local<v8::Function>::Cast(fn->Call(engine->global(), 1, args)); - m_methodConstructor = qPersistentNew<v8::Function>(createFn); - } - - v8::Local<v8::Function> connect = V8FUNCTION(Connect, engine); - v8::Local<v8::Function> disconnect = V8FUNCTION(Disconnect, engine); - - { - v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New(); - ft->InstanceTemplate()->SetHasExternalResource(true); - ft->PrototypeTemplate()->Set(v8::String::New("connect"), connect, v8::DontEnum); - ft->PrototypeTemplate()->Set(v8::String::New("disconnect"), disconnect, v8::DontEnum); - m_signalHandlerConstructor = qPersistentNew<v8::Function>(ft->GetFunction()); - } - - { - v8::Local<v8::Object> prototype = engine->global()->Get(v8::String::New("Function"))->ToObject()->Get(v8::String::New("prototype"))->ToObject(); - prototype->Set(v8::String::New("connect"), connect, v8::DontEnum); - prototype->Set(v8::String::New("disconnect"), disconnect, v8::DontEnum); - } -} - -bool QV8QObjectWrapper::isQObject(v8::Handle<v8::Object> obj) -{ - return v8_resource_cast<QV8QObjectResource>(obj) != 0; -} - -QObject *QV8QObjectWrapper::toQObject(v8::Handle<v8::Object> obj) -{ - QV8QObjectResource *r = v8_resource_cast<QV8QObjectResource>(obj); - return r?r->object:0; -} - -// r *MUST* be a QV8ObjectResource (r->type() == QV8ObjectResource::QObjectType) -QObject *QV8QObjectWrapper::toQObject(QV8ObjectResource *r) -{ - Q_ASSERT(r->resourceType() == QV8ObjectResource::QObjectType); - return static_cast<QV8QObjectResource *>(r)->object; -} - -// Load value properties -template<void (*ReadFunction)(QObject *, const QDeclarativePropertyData &, - void *, QDeclarativeNotifier **)> -static v8::Handle<v8::Value> LoadProperty(QV8Engine *engine, QObject *object, - const QDeclarativePropertyData &property, - QDeclarativeNotifier **notifier) -{ - Q_ASSERT(!property.isFunction()); - - if (property.isQObject()) { - QObject *rv = 0; - ReadFunction(object, property, &rv, notifier); - return engine->newQObject(rv); - } else if (property.isQList()) { - return engine->listWrapper()->newList(object, property.coreIndex, property.propType); - } else if (property.propType == QMetaType::QReal) { - qreal v = 0; - ReadFunction(object, property, &v, notifier); - return valueToHandle(engine, v); - } else if (property.propType == QMetaType::Int || property.isEnum()) { - int v = 0; - ReadFunction(object, property, &v, notifier); - return valueToHandle(engine, v); - } else if (property.propType == QMetaType::Bool) { - bool v = false; - ReadFunction(object, property, &v, notifier); - return valueToHandle(engine, v); - } else if (property.propType == QMetaType::QString) { - QString v; - ReadFunction(object, property, &v, notifier); - return valueToHandle(engine, v); - } else if (property.propType == QMetaType::UInt) { - uint v = 0; - ReadFunction(object, property, &v, notifier); - return valueToHandle(engine, v); - } else if (property.propType == QMetaType::Float) { - float v = 0; - ReadFunction(object, property, &v, notifier); - return valueToHandle(engine, v); - } else if (property.propType == QMetaType::Double) { - double v = 0; - ReadFunction(object, property, &v, notifier); - return valueToHandle(engine, v); - } else if (property.isV8Handle()) { - QDeclarativeV8Handle handle; - ReadFunction(object, property, &handle, notifier); - return handle.toHandle(); - } else if (property.isQVariant()) { - QVariant v; - ReadFunction(object, property, &v, notifier); - return engine->fromVariant(v); - } else if (QDeclarativeValueTypeFactory::isValueType((uint)property.propType) - && engine->engine()) { - Q_ASSERT(notifier == 0); - - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine->engine()); - QDeclarativeValueType *valueType = ep->valueTypes[property.propType]; - if (valueType) - return engine->newValueType(object, property.coreIndex, valueType); - } else { - Q_ASSERT(notifier == 0); - - // see if it's a sequence type - bool succeeded = false; - v8::Handle<v8::Value> retn = engine->newSequence(property.propType, object, property.coreIndex, - &succeeded); - if (succeeded) - return retn; - } - - if (property.propType == QVariant::Invalid) { - QMetaProperty p = object->metaObject()->property(property.coreIndex); - qWarning("QMetaProperty::read: Unable to handle unregistered datatype '%s' for property " - "'%s::%s'", p.typeName(), object->metaObject()->className(), p.name()); - return v8::Undefined(); - } else { - QVariant v(property.propType, (void *)0); - ReadFunction(object, property, v.data(), notifier); - return engine->fromVariant(v); - } -} - -v8::Handle<v8::Value> QV8QObjectWrapper::GetProperty(QV8Engine *engine, QObject *object, - v8::Handle<v8::Value> *objectHandle, - const QHashedV8String &property, - QV8QObjectWrapper::RevisionMode revisionMode) -{ - // XXX More recent versions of V8 introduced "Callable" objects. It is possible that these - // will be a faster way of creating QObject method objects. - struct MethodClosure { - static v8::Handle<v8::Value> create(QV8Engine *engine, QObject *object, - v8::Handle<v8::Value> *objectHandle, - int index) { - v8::Handle<v8::Value> argv[] = { - objectHandle?*objectHandle:engine->newQObject(object), - v8::Integer::New(index) - }; - return engine->qobjectWrapper()->m_methodConstructor->Call(engine->global(), 2, argv); - } - static v8::Handle<v8::Value> createWithGlobal(QV8Engine *engine, QObject *object, - v8::Handle<v8::Value> *objectHandle, - int index) { - v8::Handle<v8::Value> argv[] = { - objectHandle?*objectHandle:engine->newQObject(object), - v8::Integer::New(index), - v8::Context::GetCallingQmlGlobal() - }; - return engine->qobjectWrapper()->m_methodConstructor->Call(engine->global(), 3, argv); - } - }; - - { - // Comparing the hash first actually makes a measurable difference here, at least on x86 - quint32 hash = property.hash(); - if (hash == toStringHash && engine->qobjectWrapper()->m_toStringString == property) { - return MethodClosure::create(engine, object, objectHandle, QOBJECT_TOSTRING_INDEX); - } else if (hash == destroyHash && engine->qobjectWrapper()->m_destroyString == property) { - return MethodClosure::create(engine, object, objectHandle, QOBJECT_DESTROY_INDEX); - } - } - - QDeclarativePropertyData local; - QDeclarativePropertyData *result = 0; - { - QDeclarativeData *ddata = QDeclarativeData::get(object, false); - if (ddata && ddata->propertyCache) - result = ddata->propertyCache->property(property); - else - result = QDeclarativePropertyCache::property(engine->engine(), object, property, local); - } - - if (!result) - return v8::Handle<v8::Value>(); - - if (revisionMode == QV8QObjectWrapper::CheckRevision && result->revision != 0) { - QDeclarativeData *ddata = QDeclarativeData::get(object); - if (ddata && ddata->propertyCache && !ddata->propertyCache->isAllowedInRevision(result)) - return v8::Handle<v8::Value>(); - } - - if (result->isFunction()) { - if (result->isVMEFunction()) { - return ((QDeclarativeVMEMetaObject *)(object->metaObject()))->vmeMethod(result->coreIndex); - } else if (result->isV8Function()) { - return MethodClosure::createWithGlobal(engine, object, objectHandle, result->coreIndex); - } else if (result->isSignalHandler()) { - v8::Local<v8::Object> handler = engine->qobjectWrapper()->m_signalHandlerConstructor->NewInstance(); - QV8SignalHandlerResource *r = new QV8SignalHandlerResource(engine, object, result->coreIndex); - handler->SetExternalResource(r); - return handler; - } else { - return MethodClosure::create(engine, object, objectHandle, result->coreIndex); - } - } - - QDeclarativeEnginePrivate *ep = - engine->engine()?QDeclarativeEnginePrivate::get(engine->engine()):0; - - if (result->hasAccessors()) { - QDeclarativeNotifier *n = 0; - QDeclarativeNotifier **nptr = 0; - - if (ep && ep->propertyCapture && result->accessors->notifier) - nptr = &n; - - v8::Handle<v8::Value> rv = LoadProperty<ReadAccessor::Accessor>(engine, object, *result, nptr); - - if (result->accessors->notifier) { - if (n) ep->captureProperty(n); - } else { - ep->captureProperty(object, result->coreIndex, result->notifyIndex); - } - - return rv; - } - - if (ep && !result->isConstant()) { - - if (result->coreIndex == 0) - ep->captureProperty(QDeclarativeData::get(object, true)->objectNameNotifier()); - else - ep->captureProperty(object, result->coreIndex, result->notifyIndex); - } - - if (result->isVMEProperty()) { - typedef QDeclarativeVMEMetaObject VMEMO; - VMEMO *vmemo = const_cast<VMEMO *>(static_cast<const VMEMO *>(object->metaObject())); - return vmemo->vmeProperty(result->coreIndex); - } else if (result->isDirect()) { - return LoadProperty<ReadAccessor::Direct>(engine, object, *result, 0); - } else { - return LoadProperty<ReadAccessor::Indirect>(engine, object, *result, 0); - } -} - -// Setter for writable properties. Shared between the interceptor and fast property accessor -static inline void StoreProperty(QV8Engine *engine, QObject *object, QDeclarativePropertyData *property, - v8::Handle<v8::Value> value) -{ - QDeclarativeBinding *newBinding = 0; - - if (value->IsFunction()) { - QDeclarativeContextData *context = engine->callingContext(); - v8::Handle<v8::Function> function = v8::Handle<v8::Function>::Cast(value); - - v8::Local<v8::StackTrace> trace = - v8::StackTrace::CurrentStackTrace(1, (v8::StackTrace::StackTraceOptions)(v8::StackTrace::kLineNumber | - v8::StackTrace::kScriptName)); - v8::Local<v8::StackFrame> frame = trace->GetFrame(0); - int lineNumber = frame->GetLineNumber(); - int columNumber = frame->GetColumn(); - QString url = engine->toString(frame->GetScriptName()); - - newBinding = new QDeclarativeBinding(&function, object, context); - newBinding->setSourceLocation(url, lineNumber, columNumber); - newBinding->setTarget(object, *property, context); - newBinding->setEvaluateFlags(newBinding->evaluateFlags() | - QDeclarativeBinding::RequiresThisObject); - } - - QDeclarativeAbstractBinding *oldBinding = - QDeclarativePropertyPrivate::setBinding(object, property->coreIndex, -1, newBinding); - if (oldBinding) - oldBinding->destroy(); - -#define PROPERTY_STORE(cpptype, value) \ - cpptype o = value; \ - int status = -1; \ - int flags = 0; \ - void *argv[] = { &o, 0, &status, &flags }; \ - QMetaObject::metacall(object, QMetaObject::WriteProperty, property->coreIndex, argv); - - - if (value->IsNull() && property->isQObject()) { - PROPERTY_STORE(QObject*, 0); - } else if (value->IsUndefined() && property->isResettable()) { - void *a[] = { 0 }; - QMetaObject::metacall(object, QMetaObject::ResetProperty, property->coreIndex, a); - } else if (value->IsUndefined() && property->propType == qMetaTypeId<QVariant>()) { - PROPERTY_STORE(QVariant, QVariant()); - } else if (value->IsUndefined()) { - QString error = QLatin1String("Cannot assign [undefined] to ") + - QLatin1String(QMetaType::typeName(property->propType)); - v8::ThrowException(v8::Exception::Error(engine->toString(error))); - } else if (value->IsFunction()) { - // this is handled by the binding creation above - } else if (property->propType == QMetaType::Int && value->IsNumber()) { - PROPERTY_STORE(int, qRound(value->ToNumber()->Value())); - } else if (property->propType == QMetaType::QReal && value->IsNumber()) { - PROPERTY_STORE(qreal, qreal(value->ToNumber()->Value())); - } else if (property->propType == QMetaType::Float && value->IsNumber()) { - PROPERTY_STORE(float, float(value->ToNumber()->Value())); - } else if (property->propType == QMetaType::Double && value->IsNumber()) { - PROPERTY_STORE(double, double(value->ToNumber()->Value())); - } else if (property->propType == QMetaType::QString && value->IsString()) { - PROPERTY_STORE(QString, engine->toString(value->ToString())); - } else if (property->isVMEProperty()) { - static_cast<QDeclarativeVMEMetaObject *>(const_cast<QMetaObject *>(object->metaObject()))->setVMEProperty(property->coreIndex, value); - } else { - QVariant v; - if (property->isQList()) - v = engine->toVariant(value, qMetaTypeId<QList<QObject *> >()); - else - v = engine->toVariant(value, property->propType); - - QDeclarativeContextData *context = engine->callingContext(); - if (!QDeclarativePropertyPrivate::write(object, *property, v, context)) { - const char *valueType = 0; - if (v.userType() == QVariant::Invalid) valueType = "null"; - else valueType = QMetaType::typeName(v.userType()); - - QString error = QLatin1String("Cannot assign ") + - QLatin1String(valueType) + - QLatin1String(" to ") + - QLatin1String(QMetaType::typeName(property->propType)); - v8::ThrowException(v8::Exception::Error(engine->toString(error))); - } - } -} - -bool QV8QObjectWrapper::SetProperty(QV8Engine *engine, QObject *object, const QHashedV8String &property, - v8::Handle<v8::Value> value, QV8QObjectWrapper::RevisionMode revisionMode) -{ - if (engine->qobjectWrapper()->m_toStringString == property || - engine->qobjectWrapper()->m_destroyString == property) - return true; - - QDeclarativePropertyData local; - QDeclarativePropertyData *result = 0; - result = QDeclarativePropertyCache::property(engine->engine(), object, property, local); - - if (!result) - return false; - - if (revisionMode == QV8QObjectWrapper::CheckRevision && result->revision != 0) { - QDeclarativeData *ddata = QDeclarativeData::get(object); - if (ddata && ddata->propertyCache && !ddata->propertyCache->isAllowedInRevision(result)) - return false; - } - - if (!result->isWritable() && !result->isQList()) { - QString error = QLatin1String("Cannot assign to read-only property \"") + - engine->toString(property.string()) + QLatin1Char('\"'); - v8::ThrowException(v8::Exception::Error(engine->toString(error))); - return true; - } - - StoreProperty(engine, object, result, value); - - return true; -} - -v8::Handle<v8::Value> QV8QObjectWrapper::Getter(v8::Local<v8::String> property, - const v8::AccessorInfo &info) -{ - QV8QObjectResource *resource = v8_resource_check<QV8QObjectResource>(info.This()); - - if (resource->object.isNull()) - return v8::Handle<v8::Value>(); - - QObject *object = resource->object; - - QHashedV8String propertystring(property); - - QV8Engine *v8engine = resource->engine; - v8::Handle<v8::Value> This = info.This(); - v8::Handle<v8::Value> result = GetProperty(v8engine, object, &This, propertystring, - QV8QObjectWrapper::IgnoreRevision); - if (!result.IsEmpty()) - return result; - - if (QV8Engine::startsWithUpper(property)) { - // Check for attached properties - QDeclarativeContextData *context = v8engine->callingContext(); - - if (context && context->imports) { - QDeclarativeTypeNameCache::Result r = context->imports->query(propertystring); - - if (r.isValid()) { - if (r.scriptIndex != -1) { - return v8::Undefined(); - } else if (r.type) { - return v8engine->typeWrapper()->newObject(object, r.type, QV8TypeWrapper::ExcludeEnums); - } else if (r.importNamespace) { - return v8engine->typeWrapper()->newObject(object, context->imports, r.importNamespace, - QV8TypeWrapper::ExcludeEnums); - } - Q_ASSERT(!"Unreachable"); - } - } - } - - return v8::Handle<v8::Value>(); -} - -v8::Handle<v8::Value> QV8QObjectWrapper::Setter(v8::Local<v8::String> property, - v8::Local<v8::Value> value, - const v8::AccessorInfo &info) -{ - QV8QObjectResource *resource = v8_resource_check<QV8QObjectResource>(info.This()); - - if (resource->object.isNull()) - return value; - - QObject *object = resource->object; - - QHashedV8String propertystring(property); - - QV8Engine *v8engine = resource->engine; - bool result = SetProperty(v8engine, object, propertystring, value, QV8QObjectWrapper::IgnoreRevision); - - if (!result) { - QString error = QLatin1String("Cannot assign to non-existent property \"") + - v8engine->toString(property) + QLatin1Char('\"'); - v8::ThrowException(v8::Exception::Error(v8engine->toString(error))); - return value; - } - - return value; -} - -v8::Handle<v8::Integer> QV8QObjectWrapper::Query(v8::Local<v8::String> property, - const v8::AccessorInfo &info) -{ - QV8QObjectResource *resource = v8_resource_check<QV8QObjectResource>(info.This()); - - if (resource->object.isNull()) - return v8::Handle<v8::Integer>(); - - QV8Engine *engine = resource->engine; - QObject *object = resource->object; - - QHashedV8String propertystring(property); - - QDeclarativePropertyData local; - QDeclarativePropertyData *result = 0; - result = QDeclarativePropertyCache::property(engine->engine(), object, propertystring, local); - - if (!result) - return v8::Handle<v8::Integer>(); - else if (!result->isWritable() && !result->isQList()) - return v8::Integer::New(v8::ReadOnly | v8::DontDelete); - else - return v8::Integer::New(v8::DontDelete); -} - -v8::Handle<v8::Array> QV8QObjectWrapper::Enumerator(const v8::AccessorInfo &info) -{ - QV8QObjectResource *resource = v8_resource_check<QV8QObjectResource>(info.This()); - - if (resource->object.isNull()) - return v8::Array::New(); - - QObject *object = resource->object; - - QStringList result; - - QDeclarativeEnginePrivate *ep = resource->engine->engine() - ? QDeclarativeEnginePrivate::get(resource->engine->engine()) - : 0; - - QDeclarativePropertyCache *cache = 0; - QDeclarativeData *ddata = QDeclarativeData::get(object); - if (ddata) - cache = ddata->propertyCache; - - if (!cache) { - cache = ep ? ep->cache(object) : 0; - if (cache) { - if (ddata) { cache->addref(); ddata->propertyCache = cache; } - } else { - // Not cachable - fall back to QMetaObject (eg. dynamic meta object) - const QMetaObject *mo = object->metaObject(); - int pc = mo->propertyCount(); - int po = mo->propertyOffset(); - for (int i=po; i<pc; ++i) - result << QString::fromUtf8(mo->property(i).name()); - } - } else { - result = cache->propertyNames(); - } - - v8::Local<v8::Array> rv = v8::Array::New(result.count()); - - for (int ii = 0; ii < result.count(); ++ii) - rv->Set(ii, resource->engine->toString(result.at(ii))); - - return rv; -} - -static void FastValueSetter(v8::Local<v8::String>, v8::Local<v8::Value> value, - const v8::AccessorInfo& info) -{ - QV8QObjectResource *resource = v8_resource_check<QV8QObjectResource>(info.This()); - - if (resource->object.isNull()) - return; - - QObject *object = resource->object; - - QDeclarativePropertyData *property = - (QDeclarativePropertyData *)v8::External::Unwrap(info.Data()); - - int index = property->coreIndex; - - QDeclarativeData *ddata = QDeclarativeData::get(object, false); - Q_ASSERT(ddata); - Q_ASSERT(ddata->propertyCache); - - QDeclarativePropertyData *pdata = ddata->propertyCache->property(index); - Q_ASSERT(pdata); - - Q_ASSERT(pdata->isWritable() || pdata->isQList()); - - StoreProperty(resource->engine, object, pdata, value); -} - -static void FastValueSetterReadOnly(v8::Local<v8::String> property, v8::Local<v8::Value>, - const v8::AccessorInfo& info) -{ - QV8QObjectResource *resource = v8_resource_check<QV8QObjectResource>(info.This()); - - if (resource->object.isNull()) - return; - - QV8Engine *v8engine = resource->engine; - - QString error = QLatin1String("Cannot assign to read-only property \"") + - v8engine->toString(property) + QLatin1Char('\"'); - v8::ThrowException(v8::Exception::Error(v8engine->toString(error))); -} - -static void WeakQObjectReferenceCallback(v8::Persistent<v8::Value> handle, void *) -{ - Q_ASSERT(handle->IsObject()); - - QV8QObjectResource *resource = v8_resource_check<QV8QObjectResource>(handle->ToObject()); - - Q_ASSERT(resource); - - QObject *object = resource->object; - if (object) { - QDeclarativeData *ddata = QDeclarativeData::get(object, false); - if (ddata) { - ddata->v8object.Clear(); - if (!object->parent() && !ddata->indestructible) - object->deleteLater(); - } - } - - qPersistentDispose(handle); -} - -static void WeakQObjectInstanceCallback(v8::Persistent<v8::Value> handle, void *data) -{ - QV8QObjectInstance *instance = (QV8QObjectInstance *)data; - instance->v8object.Clear(); - qPersistentDispose(handle); -} - -v8::Local<v8::Object> QDeclarativePropertyCache::newQObject(QObject *object, QV8Engine *engine) -{ - Q_ASSERT(object); - Q_ASSERT(this->engine); - - Q_ASSERT(QDeclarativeData::get(object, false)); - Q_ASSERT(QDeclarativeData::get(object, false)->propertyCache == this); - - // Setup constructor - if (constructor.IsEmpty()) { - v8::Local<v8::FunctionTemplate> ft; - - QString toString = QLatin1String("toString"); - QString destroy = QLatin1String("destroy"); - - // As we use hash linking, it is possible that iterating over the values can give duplicates. - // To combat this, we must unique'ify our properties. - StringCache uniqueHash; - if (stringCache.isLinked()) - uniqueHash.reserve(stringCache.count()); - - // XXX TODO: Enables fast property accessors. These more than double the property access - // performance, but the cost of setting up this structure hasn't been measured so - // its not guarenteed that this is a win overall. We need to try and measure the cost. - for (StringCache::ConstIterator iter = stringCache.begin(); iter != stringCache.end(); ++iter) { - if (stringCache.isLinked()) { - if (uniqueHash.contains(iter)) - continue; - uniqueHash.insert(iter); - } - - QDeclarativePropertyData *property = *iter; - if (property->notFullyResolved()) resolve(property); - - if (property->isFunction()) - continue; - - v8::AccessorGetter fastgetter = 0; - v8::AccessorSetter fastsetter = FastValueSetter; - if (!property->isWritable()) - fastsetter = FastValueSetterReadOnly; - - if (property->isQObject()) - fastgetter = FAST_GETTER_FUNCTION(property, QObject*); - else if (property->propType == QMetaType::Int || property->isEnum()) - fastgetter = FAST_GETTER_FUNCTION(property, int); - else if (property->propType == QMetaType::Bool) - fastgetter = FAST_GETTER_FUNCTION(property, bool); - else if (property->propType == QMetaType::QString) - fastgetter = FAST_GETTER_FUNCTION(property, QString); - else if (property->propType == QMetaType::UInt) - fastgetter = FAST_GETTER_FUNCTION(property, uint); - else if (property->propType == QMetaType::Float) - fastgetter = FAST_GETTER_FUNCTION(property, float); - else if (property->propType == QMetaType::Double) - fastgetter = FAST_GETTER_FUNCTION(property, double); - - if (fastgetter) { - QString name = iter.key(); - if (name == toString || name == destroy) - continue; - - if (ft.IsEmpty()) { - ft = v8::FunctionTemplate::New(); - ft->InstanceTemplate()->SetFallbackPropertyHandler(QV8QObjectWrapper::Getter, - QV8QObjectWrapper::Setter, - QV8QObjectWrapper::Query, - 0, - QV8QObjectWrapper::Enumerator); - ft->InstanceTemplate()->SetHasExternalResource(true); - } - - // We wrap the raw QDeclarativePropertyData pointer here. This is safe as the - // pointer will remain valid at least as long as the lifetime of any QObject's of - // this type and the property accessor checks if the object is 0 (deleted) before - // dereferencing the pointer. - ft->InstanceTemplate()->SetAccessor(engine->toString(name), fastgetter, fastsetter, - v8::External::Wrap(property)); - } - } - - if (ft.IsEmpty()) { - constructor = qPersistentNew<v8::Function>(engine->qobjectWrapper()->m_constructor); - } else { - ft->InstanceTemplate()->SetFallbackPropertyHandler(QV8QObjectWrapper::Getter, - QV8QObjectWrapper::Setter, - QV8QObjectWrapper::Query, - 0, - QV8QObjectWrapper::Enumerator); - ft->InstanceTemplate()->SetHasExternalResource(true); - constructor = qPersistentNew<v8::Function>(ft->GetFunction()); - } - - QDeclarativeCleanup::addToEngine(this->engine); - } - - v8::Local<v8::Object> result = constructor->NewInstance(); - QV8QObjectResource *r = new QV8QObjectResource(engine, object); - result->SetExternalResource(r); - return result; -} - -v8::Local<v8::Object> QV8QObjectWrapper::newQObject(QObject *object, QDeclarativeData *ddata, QV8Engine *engine) -{ - v8::Local<v8::Object> rv; - - if (!ddata->propertyCache && engine->engine()) { - ddata->propertyCache = QDeclarativeEnginePrivate::get(engine->engine())->cache(object); - if (ddata->propertyCache) ddata->propertyCache->addref(); - } - - if (ddata->propertyCache && ddata->propertyCache->qmlEngine() == engine->engine()) { - rv = ddata->propertyCache->newQObject(object, engine); - } else { - // XXX NewInstance() should be optimized - rv = m_constructor->NewInstance(); - QV8QObjectResource *r = new QV8QObjectResource(engine, object); - rv->SetExternalResource(r); - } - - return rv; -} - -/* -As V8 doesn't support an equality callback, for QObject's we have to return exactly the same -V8 handle for subsequent calls to newQObject for the same QObject. To do this we have a two -pronged strategy: - 1. If there is no current outstanding V8 handle to the QObject, we create one and store a - persistent handle in QDeclarativeData::v8object. We mark the QV8QObjectWrapper that - "owns" this handle by setting the QDeclarativeData::v8objectid to the id of this - QV8QObjectWrapper. - 2. If another QV8QObjectWrapper has create the handle in QDeclarativeData::v8object we create - an entry in the m_taintedObject hash where we store the handle and mark the object as - "tainted" in the QDeclarativeData::hasTaintedV8Object flag. -We have to mark the object as tainted to ensure that we search our m_taintedObject hash even -in the case that the original QV8QObjectWrapper owner of QDeclarativeData::v8object has -released the handle. -*/ -v8::Handle<v8::Value> QV8QObjectWrapper::newQObject(QObject *object) -{ - if (!object) - return v8::Null(); - - if (QObjectPrivate::get(object)->wasDeleted) - return v8::Undefined(); - - QDeclarativeData *ddata = QDeclarativeData::get(object, true); - - if (!ddata) - return v8::Undefined(); - - if (ddata->v8objectid == m_id && !ddata->v8object.IsEmpty()) { - // We own the v8object - return v8::Local<v8::Object>::New(ddata->v8object); - } else if (ddata->v8object.IsEmpty() && - (ddata->v8objectid == m_id || // We own the QObject - ddata->v8objectid == 0 || // No one owns the QObject - !ddata->hasTaintedV8Object)) { // Someone else has used the QObject, but it isn't tainted - - v8::Local<v8::Object> rv = newQObject(object, ddata, m_engine); - ddata->v8object = qPersistentNew<v8::Object>(rv); - ddata->v8object.MakeWeak(0, WeakQObjectReferenceCallback); - ddata->v8objectid = m_id; - return rv; - - } else { - // If this object is tainted, we have to check to see if it is in our - // tainted object list - TaintedHash::Iterator iter = - ddata->hasTaintedV8Object?m_taintedObjects.find(object):m_taintedObjects.end(); - bool found = iter != m_taintedObjects.end(); - - // If our tainted handle doesn't exist or has been collected, and there isn't - // a handle in the ddata, we can assume ownership of the ddata->v8object - if ((!found || (*iter)->v8object.IsEmpty()) && ddata->v8object.IsEmpty()) { - v8::Local<v8::Object> rv = newQObject(object, ddata, m_engine); - ddata->v8object = qPersistentNew<v8::Object>(rv); - ddata->v8object.MakeWeak(0, WeakQObjectReferenceCallback); - ddata->v8objectid = m_id; - - if (found) { - delete (*iter); - m_taintedObjects.erase(iter); - } - - return rv; - } else if (!found) { - QV8QObjectInstance *instance = new QV8QObjectInstance(object, this); - iter = m_taintedObjects.insert(object, instance); - ddata->hasTaintedV8Object = true; - } - - if ((*iter)->v8object.IsEmpty()) { - v8::Local<v8::Object> rv = newQObject(object, ddata, m_engine); - (*iter)->v8object = qPersistentNew<v8::Object>(rv); - (*iter)->v8object.MakeWeak((*iter), WeakQObjectInstanceCallback); - } - - return v8::Local<v8::Object>::New((*iter)->v8object); - } -} - -QPair<QObject *, int> QV8QObjectWrapper::ExtractQtSignal(QV8Engine *engine, v8::Handle<v8::Object> object) -{ - if (object->IsFunction()) - return ExtractQtMethod(engine, v8::Handle<v8::Function>::Cast(object)); - - if (QV8SignalHandlerResource *resource = v8_resource_cast<QV8SignalHandlerResource>(object)) - return qMakePair(resource->object.data(), resource->index); - - return qMakePair((QObject *)0, -1); -} - -QPair<QObject *, int> QV8QObjectWrapper::ExtractQtMethod(QV8Engine *engine, v8::Handle<v8::Function> function) -{ - v8::ScriptOrigin origin = function->GetScriptOrigin(); - if (origin.ResourceName()->StrictEquals(engine->qobjectWrapper()->m_hiddenObject)) { - - // This is one of our special QObject method wrappers - v8::Handle<v8::Value> args[] = { engine->qobjectWrapper()->m_hiddenObject }; - v8::Local<v8::Value> data = function->Call(engine->global(), 1, args); - - if (data->IsArray()) { - v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(data); - return qMakePair(engine->toQObject(array->Get(0)), array->Get(1)->Int32Value()); - } - - // In theory this can't fall through, but I suppose V8 might run out of memory or something - } - - return qMakePair((QObject *)0, -1); -} - -class QV8QObjectConnectionList : public QObject, public QDeclarativeGuard<QObject> -{ -public: - QV8QObjectConnectionList(QObject *object, QV8Engine *engine); - ~QV8QObjectConnectionList(); - - struct Connection { - Connection() - : needsDestroy(false) {} - Connection(const Connection &other) - : thisObject(other.thisObject), function(other.function), needsDestroy(false) {} - Connection &operator=(const Connection &other) { - thisObject = other.thisObject; - function = other.function; - needsDestroy = other.needsDestroy; - return *this; - } - - v8::Persistent<v8::Object> thisObject; - v8::Persistent<v8::Function> function; - - void dispose() { - qPersistentDispose(thisObject); - qPersistentDispose(function); - } - - bool needsDestroy; - }; - - struct ConnectionList : public QList<Connection> { - ConnectionList() : connectionsInUse(0), connectionsNeedClean(false) {} - int connectionsInUse; - bool connectionsNeedClean; - }; - - QV8Engine *engine; - - typedef QHash<int, ConnectionList> SlotHash; - SlotHash slotHash; - bool needsDestroy; - int inUse; - - virtual void objectDestroyed(QObject *); - virtual int qt_metacall(QMetaObject::Call, int, void **); -}; - -QV8QObjectConnectionList::QV8QObjectConnectionList(QObject *object, QV8Engine *engine) -: QDeclarativeGuard<QObject>(object), engine(engine), needsDestroy(false), inUse(0) -{ -} - -QV8QObjectConnectionList::~QV8QObjectConnectionList() -{ - for (SlotHash::Iterator iter = slotHash.begin(); iter != slotHash.end(); ++iter) { - QList<Connection> &connections = *iter; - for (int ii = 0; ii < connections.count(); ++ii) { - qPersistentDispose(connections[ii].thisObject); - qPersistentDispose(connections[ii].function); - } - } - slotHash.clear(); -} - -void QV8QObjectConnectionList::objectDestroyed(QObject *object) -{ - engine->qobjectWrapper()->m_connections.remove(object); - - if (inUse) - needsDestroy = true; - else - delete this; -} - -int QV8QObjectConnectionList::qt_metacall(QMetaObject::Call method, int index, void **metaArgs) -{ - if (method == QMetaObject::InvokeMetaMethod) { - SlotHash::Iterator iter = slotHash.find(index); - if (iter == slotHash.end()) - return -1; - ConnectionList &connectionList = *iter; - if (connectionList.isEmpty()) - return -1; - - inUse++; - - connectionList.connectionsInUse++; - - QList<Connection> connections = connectionList; - - QVarLengthArray<int, 9> dummy; - int *argsTypes = QDeclarativePropertyCache::methodParameterTypes(data(), index, dummy, 0); - - v8::HandleScope handle_scope; - v8::Context::Scope scope(engine->context()); - - int argCount = argsTypes?argsTypes[0]:0; - QVarLengthArray<v8::Handle<v8::Value>, 9> args(argCount); - - for (int ii = 0; ii < argCount; ++ii) { - int type = argsTypes[ii + 1]; - if (type == qMetaTypeId<QVariant>()) { - args[ii] = engine->fromVariant(*((QVariant *)metaArgs[ii + 1])); - } else { - args[ii] = engine->fromVariant(QVariant(type, metaArgs[ii + 1])); - } - } - - for (int ii = 0; ii < connections.count(); ++ii) { - Connection &connection = connections[ii]; - if (connection.needsDestroy) - continue; - - v8::TryCatch try_catch; - if (connection.thisObject.IsEmpty()) { - connection.function->Call(engine->global(), argCount, args.data()); - } else { - connection.function->Call(connection.thisObject, argCount, args.data()); - } - - if (try_catch.HasCaught()) { - QDeclarativeError error; - error.setDescription(QString(QLatin1String("Unknown exception occurred during evaluation of connected function: %1")).arg(engine->toString(connection.function->GetName()))); - v8::Local<v8::Message> message = try_catch.Message(); - if (!message.IsEmpty()) - QDeclarativeExpressionPrivate::exceptionToError(message, error); - QDeclarativeEnginePrivate::get(engine->engine())->warning(error); - } - } - - connectionList.connectionsInUse--; - if (connectionList.connectionsInUse == 0 && connectionList.connectionsNeedClean) { - for (QList<Connection>::Iterator iter = connectionList.begin(); - iter != connectionList.end(); ) { - if (iter->needsDestroy) { - iter->dispose(); - iter = connectionList.erase(iter); - } else { - ++iter; - } - } - } - - inUse--; - if (inUse == 0 && needsDestroy) - delete this; - } - - return -1; -} - -v8::Handle<v8::Value> QV8QObjectWrapper::Connect(const v8::Arguments &args) -{ - if (args.Length() == 0) - V8THROW_ERROR("Function.prototype.connect: no arguments given"); - - QV8Engine *engine = V8ENGINE(); - - QPair<QObject *, int> signalInfo = ExtractQtSignal(engine, args.This()); - QObject *signalObject = signalInfo.first; - int signalIndex = signalInfo.second; - - if (signalIndex == -1) - V8THROW_ERROR("Function.prototype.connect: this object is not a signal"); - - if (!signalObject) - V8THROW_ERROR("Function.prototype.connect: cannot connect to deleted QObject"); - - if (signalIndex < 0 || signalObject->metaObject()->method(signalIndex).methodType() != QMetaMethod::Signal) - V8THROW_ERROR("Function.prototype.connect: this object is not a signal"); - - v8::Local<v8::Value> functionValue; - v8::Local<v8::Value> functionThisValue; - - if (args.Length() == 1) { - functionValue = args[0]; - } else { - functionThisValue = args[0]; - functionValue = args[1]; - } - - if (!functionValue->IsFunction()) - V8THROW_ERROR("Function.prototype.connect: target is not a function"); - - if (!functionThisValue.IsEmpty() && !functionThisValue->IsObject()) - V8THROW_ERROR("Function.prototype.connect: target this is not an object"); - - QV8QObjectWrapper *qobjectWrapper = engine->qobjectWrapper(); - QHash<QObject *, QV8QObjectConnectionList *> &connections = qobjectWrapper->m_connections; - QHash<QObject *, QV8QObjectConnectionList *>::Iterator iter = connections.find(signalObject); - if (iter == connections.end()) - iter = connections.insert(signalObject, new QV8QObjectConnectionList(signalObject, engine)); - - QV8QObjectConnectionList *connectionList = *iter; - QV8QObjectConnectionList::SlotHash::Iterator slotIter = connectionList->slotHash.find(signalIndex); - if (slotIter == connectionList->slotHash.end()) { - slotIter = connectionList->slotHash.insert(signalIndex, QV8QObjectConnectionList::ConnectionList()); - QMetaObject::connect(signalObject, signalIndex, connectionList, signalIndex); - } - - QV8QObjectConnectionList::Connection connection; - if (!functionThisValue.IsEmpty()) - connection.thisObject = qPersistentNew<v8::Object>(functionThisValue->ToObject()); - connection.function = qPersistentNew<v8::Function>(v8::Handle<v8::Function>::Cast(functionValue)); - - slotIter->append(connection); - - return v8::Undefined(); -} - -v8::Handle<v8::Value> QV8QObjectWrapper::Disconnect(const v8::Arguments &args) -{ - if (args.Length() == 0) - V8THROW_ERROR("Function.prototype.disconnect: no arguments given"); - - QV8Engine *engine = V8ENGINE(); - - QPair<QObject *, int> signalInfo = ExtractQtSignal(engine, args.This()); - QObject *signalObject = signalInfo.first; - int signalIndex = signalInfo.second; - - if (signalIndex == -1) - V8THROW_ERROR("Function.prototype.disconnect: this object is not a signal"); - - if (!signalObject) - V8THROW_ERROR("Function.prototype.disconnect: cannot disconnect from deleted QObject"); - - if (signalIndex < 0 || signalObject->metaObject()->method(signalIndex).methodType() != QMetaMethod::Signal) - V8THROW_ERROR("Function.prototype.disconnect: this object is not a signal"); - - v8::Local<v8::Value> functionValue; - v8::Local<v8::Value> functionThisValue; - - if (args.Length() == 1) { - functionValue = args[0]; - } else { - functionThisValue = args[0]; - functionValue = args[1]; - } - - if (!functionValue->IsFunction()) - V8THROW_ERROR("Function.prototype.disconnect: target is not a function"); - - if (!functionThisValue.IsEmpty() && !functionThisValue->IsObject()) - V8THROW_ERROR("Function.prototype.disconnect: target this is not an object"); - - QV8QObjectWrapper *qobjectWrapper = engine->qobjectWrapper(); - QHash<QObject *, QV8QObjectConnectionList *> &connectionsList = qobjectWrapper->m_connections; - QHash<QObject *, QV8QObjectConnectionList *>::Iterator iter = connectionsList.find(signalObject); - if (iter == connectionsList.end()) - return v8::Undefined(); // Nothing to disconnect from - - QV8QObjectConnectionList *connectionList = *iter; - QV8QObjectConnectionList::SlotHash::Iterator slotIter = connectionList->slotHash.find(signalIndex); - if (slotIter == connectionList->slotHash.end()) - return v8::Undefined(); // Nothing to disconnect from - - QV8QObjectConnectionList::ConnectionList &connections = *slotIter; - - v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(functionValue); - QPair<QObject *, int> functionData = ExtractQtMethod(engine, function); - - if (functionData.second != -1) { - // This is a QObject function wrapper - for (int ii = 0; ii < connections.count(); ++ii) { - QV8QObjectConnectionList::Connection &connection = connections[ii]; - - if (connection.thisObject.IsEmpty() == functionThisValue.IsEmpty() && - (connection.thisObject.IsEmpty() || connection.thisObject->StrictEquals(functionThisValue))) { - - QPair<QObject *, int> connectedFunctionData = ExtractQtMethod(engine, connection.function); - if (connectedFunctionData == functionData) { - // Match! - if (connections.connectionsInUse) { - connection.needsDestroy = true; - connections.connectionsNeedClean = true; - } else { - connection.dispose(); - connections.removeAt(ii); - } - return v8::Undefined(); - } - } - } - - } else { - // This is a normal JS function - for (int ii = 0; ii < connections.count(); ++ii) { - QV8QObjectConnectionList::Connection &connection = connections[ii]; - if (connection.function->StrictEquals(function) && - connection.thisObject.IsEmpty() == functionThisValue.IsEmpty() && - (connection.thisObject.IsEmpty() || connection.thisObject->StrictEquals(functionThisValue))) { - // Match! - if (connections.connectionsInUse) { - connection.needsDestroy = true; - connections.connectionsNeedClean = true; - } else { - connection.dispose(); - connections.removeAt(ii); - } - return v8::Undefined(); - } - } - } - - return v8::Undefined(); -} - -/*! - \fn v8::Handle<v8::Value> QV8QObjectWrapper::getProperty(QObject *object, const QHashedV8String &property, QV8QObjectWrapper::RevisionMode revisionMode) - - Get the \a property of \a object. Returns an empty handle if the property doesn't exist. - - Only searches for real properties of \a object (including methods), not attached properties etc. -*/ - -/* - \fn bool QV8QObjectWrapper::setProperty(QObject *object, const QHashedV8String &property, v8::Handle<v8::Value> value, RevisionMode revisionMode) - - Set the \a property of \a object to \a value. - - Returns true if the property was "set" - even if this results in an exception being thrown - - and false if the object has no such property. - - Only searches for real properties of \a object (including methods), not attached properties etc. -*/ - -namespace { -struct CallArgs -{ - CallArgs(int length, v8::Handle<v8::Object> *args) : _length(length), _args(args) {} - int Length() const { return _length; } - v8::Local<v8::Value> operator[](int idx) { return (*_args)->Get(idx); } - -private: - int _length; - v8::Handle<v8::Object> *_args; -}; -} - -static v8::Handle<v8::Value> CallMethod(QObject *object, int index, int returnType, int argCount, - int *argTypes, QV8Engine *engine, CallArgs &callArgs) -{ - if (argCount > 0) { - - QVarLengthArray<CallArgument, 9> args(argCount + 1); - args[0].initAsType(returnType); - - for (int ii = 0; ii < argCount; ++ii) - args[ii + 1].fromValue(argTypes[ii], engine, callArgs[ii]); - - QVarLengthArray<void *, 9> argData(args.count()); - for (int ii = 0; ii < args.count(); ++ii) - argData[ii] = args[ii].dataPtr(); - - QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, index, argData.data()); - - return args[0].toValue(engine); - - } else if (returnType != 0) { - - CallArgument arg; - arg.initAsType(returnType); - - void *args[] = { arg.dataPtr() }; - - QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, index, args); - - return arg.toValue(engine); - - } else { - - void *args[] = { 0 }; - QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, index, args); - return v8::Undefined(); - - } -} - -/*! - Returns the match score for converting \a actual to be of type \a conversionType. A - zero score means "perfect match" whereas a higher score is worse. - - The conversion table is copied out of the QtScript callQtMethod() function. -*/ -static int MatchScore(v8::Handle<v8::Value> actual, int conversionType) -{ - if (actual->IsNumber()) { - switch (conversionType) { - case QMetaType::Double: - return 0; - case QMetaType::Float: - return 1; - case QMetaType::LongLong: - case QMetaType::ULongLong: - return 2; - case QMetaType::Long: - case QMetaType::ULong: - return 3; - case QMetaType::Int: - case QMetaType::UInt: - return 4; - case QMetaType::Short: - case QMetaType::UShort: - return 5; - break; - case QMetaType::Char: - case QMetaType::UChar: - return 6; - default: - return 10; - } - } else if (actual->IsString()) { - switch (conversionType) { - case QMetaType::QString: - return 0; - default: - return 10; - } - } else if (actual->IsBoolean()) { - switch (conversionType) { - case QMetaType::Bool: - return 0; - default: - return 10; - } - } else if (actual->IsDate()) { - switch (conversionType) { - case QMetaType::QDateTime: - return 0; - case QMetaType::QDate: - return 1; - case QMetaType::QTime: - return 2; - default: - return 10; - } - } else if (actual->IsRegExp()) { - switch (conversionType) { - case QMetaType::QRegExp: - return 0; - default: - return 10; - } - } else if (actual->IsArray()) { - switch (conversionType) { - case QMetaType::QStringList: - case QMetaType::QVariantList: - return 5; - default: - return 10; - } - } else if (actual->IsNull()) { - switch (conversionType) { - case QMetaType::VoidStar: - case QMetaType::QObjectStar: - return 0; - default: { - const char *typeName = QMetaType::typeName(conversionType); - if (typeName && typeName[strlen(typeName) - 1] == '*') - return 0; - else - return 10; - } - } - } else if (actual->IsObject()) { - v8::Handle<v8::Object> obj = v8::Handle<v8::Object>::Cast(actual); - - QV8ObjectResource *r = static_cast<QV8ObjectResource *>(obj->GetExternalResource()); - if (r && r->resourceType() == QV8ObjectResource::QObjectType) { - switch (conversionType) { - case QMetaType::QObjectStar: - return 0; - default: - return 10; - } - } else if (r && r->resourceType() == QV8ObjectResource::VariantType) { - if (conversionType == qMetaTypeId<QVariant>()) - return 0; - else if (r->engine->toVariant(actual, -1).userType() == conversionType) - return 0; - else - return 10; - } else { - return 10; - } - - } else { - return 10; - } -} - -static inline int QMetaObject_methods(const QMetaObject *metaObject) -{ - struct Private - { - int revision; - int className; - int classInfoCount, classInfoData; - int methodCount, methodData; - }; - - return reinterpret_cast<const Private *>(metaObject->d.data)->methodCount; -} - -static QByteArray QMetaMethod_name(const QMetaMethod &m) -{ - QByteArray sig = m.signature(); - int paren = sig.indexOf('('); - if (paren == -1) - return sig; - else - return sig.left(paren); -} - -/*! -Returns the next related method, if one, or 0. -*/ -static const QDeclarativePropertyData * RelatedMethod(QObject *object, - const QDeclarativePropertyData *current, - QDeclarativePropertyData &dummy) -{ - QDeclarativePropertyCache *cache = QDeclarativeData::get(object)->propertyCache; - if (!current->isOverload()) - return 0; - - Q_ASSERT(!current->overrideIndexIsProperty); - - if (cache) { - return cache->method(current->overrideIndex); - } else { - const QMetaObject *mo = object->metaObject(); - int methodOffset = mo->methodCount() - QMetaObject_methods(mo); - - while (methodOffset > current->overrideIndex) { - mo = mo->superClass(); - methodOffset -= QMetaObject_methods(mo); - } - - QMetaMethod method = mo->method(current->overrideIndex); - dummy.load(method); - - // Look for overloaded methods - QByteArray methodName = QMetaMethod_name(method); - for (int ii = current->overrideIndex - 1; ii >= methodOffset; --ii) { - if (methodName == QMetaMethod_name(mo->method(ii))) { - dummy.setFlags(dummy.getFlags() | QDeclarativePropertyData::IsOverload); - dummy.overrideIndexIsProperty = 0; - dummy.overrideIndex = ii; - return &dummy; - } - } - - return &dummy; - } -} - -static v8::Handle<v8::Value> CallPrecise(QObject *object, const QDeclarativePropertyData &data, - QV8Engine *engine, CallArgs &callArgs) -{ - if (data.hasArguments()) { - - int *args = 0; - QVarLengthArray<int, 9> dummy; - QByteArray unknownTypeError; - - args = QDeclarativePropertyCache::methodParameterTypes(object, data.coreIndex, dummy, - &unknownTypeError); - - if (!args) { - QString typeName = QString::fromLatin1(unknownTypeError); - QString error = QString::fromLatin1("Unknown method parameter type: %1").arg(typeName); - v8::ThrowException(v8::Exception::Error(engine->toString(error))); - return v8::Handle<v8::Value>(); - } - - if (args[0] > callArgs.Length()) { - QString error = QLatin1String("Insufficient arguments"); - v8::ThrowException(v8::Exception::Error(engine->toString(error))); - return v8::Handle<v8::Value>(); - } - - return CallMethod(object, data.coreIndex, data.propType, args[0], args + 1, engine, callArgs); - - } else { - - return CallMethod(object, data.coreIndex, data.propType, 0, 0, engine, callArgs); - - } -} - -/*! -Resolve the overloaded method to call. The algorithm works conceptually like this: - 1. Resolve the set of overloads it is *possible* to call. - Impossible overloads include those that have too many parameters or have parameters - of unknown type. - 2. Filter the set of overloads to only contain those with the closest number of - parameters. - For example, if we are called with 3 parameters and there are 2 overloads that - take 2 parameters and one that takes 3, eliminate the 2 parameter overloads. - 3. Find the best remaining overload based on its match score. - If two or more overloads have the same match score, call the last one. The match - score is constructed by adding the matchScore() result for each of the parameters. -*/ -static v8::Handle<v8::Value> CallOverloaded(QObject *object, const QDeclarativePropertyData &data, - QV8Engine *engine, CallArgs &callArgs) -{ - int argumentCount = callArgs.Length(); - - const QDeclarativePropertyData *best = 0; - int bestParameterScore = INT_MAX; - int bestMatchScore = INT_MAX; - - QDeclarativePropertyData dummy; - const QDeclarativePropertyData *attempt = &data; - - do { - QVarLengthArray<int, 9> dummy; - int methodArgumentCount = 0; - int *methodArgTypes = 0; - if (attempt->hasArguments()) { - typedef QDeclarativePropertyCache PC; - int *args = PC::methodParameterTypes(object, attempt->coreIndex, dummy, 0); - if (!args) // Must be an unknown argument - continue; - - methodArgumentCount = args[0]; - methodArgTypes = args + 1; - } - - if (methodArgumentCount > argumentCount) - continue; // We don't have sufficient arguments to call this method - - int methodParameterScore = argumentCount - methodArgumentCount; - if (methodParameterScore > bestParameterScore) - continue; // We already have a better option - - int methodMatchScore = 0; - for (int ii = 0; ii < methodArgumentCount; ++ii) - methodMatchScore += MatchScore(callArgs[ii], methodArgTypes[ii]); - - if (bestParameterScore > methodParameterScore || bestMatchScore > methodMatchScore) { - best = attempt; - bestParameterScore = methodParameterScore; - bestMatchScore = methodMatchScore; - } - - if (bestParameterScore == 0 && bestMatchScore == 0) - break; // We can't get better than that - - } while((attempt = RelatedMethod(object, attempt, dummy)) != 0); - - if (best) { - return CallPrecise(object, *best, engine, callArgs); - } else { - QString error = QLatin1String("Unable to determine callable overload. Candidates are:"); - const QDeclarativePropertyData *candidate = &data; - while (candidate) { - error += QLatin1String("\n ") + - QString::fromUtf8(object->metaObject()->method(candidate->coreIndex).signature()); - candidate = RelatedMethod(object, candidate, dummy); - } - - v8::ThrowException(v8::Exception::Error(engine->toString(error))); - return v8::Handle<v8::Value>(); - } -} - -static v8::Handle<v8::Value> ToString(QV8Engine *engine, QObject *object, int, v8::Handle<v8::Object>) -{ - QString result; - if (object) { - QString objectName = object->objectName(); - - result += QString::fromUtf8(object->metaObject()->className()); - result += QLatin1String("(0x"); - result += QString::number((quintptr)object,16); - - if (!objectName.isEmpty()) { - result += QLatin1String(", \""); - result += objectName; - result += QLatin1Char('\"'); - } - - result += QLatin1Char(')'); - } else { - result = QLatin1String("null"); - } - - return engine->toString(result); -} - -static v8::Handle<v8::Value> Destroy(QV8Engine *, QObject *object, int argCount, v8::Handle<v8::Object> args) -{ - QDeclarativeData *ddata = QDeclarativeData::get(object, false); - if (!ddata || ddata->indestructible) { - const char *error = "Invalid attempt to destroy() an indestructible object"; - v8::ThrowException(v8::Exception::Error(v8::String::New(error))); - return v8::Undefined(); - } - - int delay = 0; - if (argCount > 0) - delay = args->Get(0)->Uint32Value(); - - if (delay > 0) - QTimer::singleShot(delay, object, SLOT(deleteLater())); - else - object->deleteLater(); - - return v8::Undefined(); -} - -v8::Handle<v8::Value> QV8QObjectWrapper::Invoke(const v8::Arguments &args) -{ - // object, index, qmlglobal, argCount, args - Q_ASSERT(args.Length() == 5); - Q_ASSERT(args[0]->IsObject()); - - QV8QObjectResource *resource = v8_resource_cast<QV8QObjectResource>(args[0]->ToObject()); - - if (!resource) - return v8::Undefined(); - - int argCount = args[3]->Int32Value(); - v8::Handle<v8::Object> arguments = v8::Handle<v8::Object>::Cast(args[4]); - - // Special hack to return info about this closure. - if (argCount == 1 && arguments->Get(0)->StrictEquals(resource->engine->qobjectWrapper()->m_hiddenObject)) { - v8::Local<v8::Array> data = v8::Array::New(2); - data->Set(0, args[0]); - data->Set(1, args[1]); - return data; - } - - QObject *object = resource->object; - int index = args[1]->Int32Value(); - - if (!object) - return v8::Undefined(); - - if (index < 0) { - // Builtin functions - if (index == QOBJECT_TOSTRING_INDEX) { - return ToString(resource->engine, object, argCount, arguments); - } else if (index == QOBJECT_DESTROY_INDEX) { - return Destroy(resource->engine, object, argCount, arguments); - } else { - return v8::Undefined(); - } - } - - QDeclarativePropertyData method; - - if (QDeclarativeData *ddata = static_cast<QDeclarativeData *>(QObjectPrivate::get(object)->declarativeData)) { - if (ddata->propertyCache) { - QDeclarativePropertyData *d = ddata->propertyCache->method(index); - if (!d) - return v8::Undefined(); - method = *d; - } - } - - if (method.coreIndex == -1) { - method.load(object->metaObject()->method(index)); - - if (method.coreIndex == -1) - return v8::Undefined(); - } - - if (method.isV8Function()) { - v8::Handle<v8::Value> rv; - v8::Handle<v8::Object> qmlglobal = args[2]->ToObject(); - - QDeclarativeV8Function func(argCount, arguments, rv, qmlglobal, - resource->engine->contextWrapper()->context(qmlglobal), - resource->engine); - QDeclarativeV8Function *funcptr = &func; - - void *args[] = { 0, &funcptr }; - QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, method.coreIndex, args); - - if (rv.IsEmpty()) return v8::Undefined(); - return rv; - } - - CallArgs callArgs(argCount, &arguments); - if (!method.isOverload()) { - return CallPrecise(object, method, resource->engine, callArgs); - } else { - return CallOverloaded(object, method, resource->engine, callArgs); - } -} - -CallArgument::CallArgument() -: type(QVariant::Invalid) -{ -} - -CallArgument::~CallArgument() -{ - cleanup(); -} - -void CallArgument::cleanup() -{ - if (type == QMetaType::QString) { - qstringPtr->~QString(); - } else if (type == -1 || type == QMetaType::QVariant) { - qvariantPtr->~QVariant(); - } else if (type == qMetaTypeId<QJSValue>()) { - qjsValuePtr->~QJSValue(); - } else if (type == qMetaTypeId<QList<QObject *> >()) { - qlistPtr->~QList<QObject *>(); - } -} - -void *CallArgument::dataPtr() -{ - if (type == -1) - return qvariantPtr->data(); - else - return (void *)&allocData; -} - -void CallArgument::initAsType(int callType) -{ - if (type != 0) { cleanup(); type = 0; } - if (callType == 0) return; - - if (callType == qMetaTypeId<QJSValue>()) { - qjsValuePtr = new (&allocData) QJSValue(); - type = callType; - } else if (callType == QMetaType::Int || - callType == QMetaType::UInt || - callType == QMetaType::Bool || - callType == QMetaType::Double || - callType == QMetaType::Float) { - type = callType; - } else if (callType == QMetaType::QObjectStar) { - qobjectPtr = 0; - type = callType; - } else if (callType == QMetaType::QString) { - qstringPtr = new (&allocData) QString(); - type = callType; - } else if (callType == QMetaType::QVariant) { - type = callType; - qvariantPtr = new (&allocData) QVariant(); - } else if (callType == qMetaTypeId<QList<QObject *> >()) { - type = callType; - qlistPtr = new (&allocData) QList<QObject *>(); - } else if (callType == qMetaTypeId<QDeclarativeV8Handle>()) { - type = callType; - handlePtr = new (&allocData) QDeclarativeV8Handle; - } else { - type = -1; - qvariantPtr = new (&allocData) QVariant(callType, (void *)0); - } -} - -void CallArgument::fromValue(int callType, QV8Engine *engine, v8::Handle<v8::Value> value) -{ - if (type != 0) { cleanup(); type = 0; } - - if (callType == qMetaTypeId<QJSValue>()) { - qjsValuePtr = new (&allocData) QJSValue(QJSValuePrivate::get(new QJSValuePrivate(engine, value))); - type = qMetaTypeId<QJSValue>(); - } else if (callType == QMetaType::Int) { - intValue = quint32(value->Int32Value()); - type = callType; - } else if (callType == QMetaType::UInt) { - intValue = quint32(value->Uint32Value()); - type = callType; - } else if (callType == QMetaType::Bool) { - boolValue = value->BooleanValue(); - type = callType; - } else if (callType == QMetaType::Double) { - doubleValue = double(value->NumberValue()); - type = callType; - } else if (callType == QMetaType::Float) { - floatValue = float(value->NumberValue()); - type = callType; - } else if (callType == QMetaType::QString) { - if (value->IsNull() || value->IsUndefined()) - qstringPtr = new (&allocData) QString(); - else - qstringPtr = new (&allocData) QString(engine->toString(value->ToString())); - type = callType; - } else if (callType == QMetaType::QObjectStar) { - qobjectPtr = engine->toQObject(value); - type = callType; - } else if (callType == qMetaTypeId<QVariant>()) { - qvariantPtr = new (&allocData) QVariant(engine->toVariant(value, -1)); - type = callType; - } else if (callType == qMetaTypeId<QList<QObject*> >()) { - qlistPtr = new (&allocData) QList<QObject *>(); - if (value->IsArray()) { - v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(value); - uint32_t length = array->Length(); - for (uint32_t ii = 0; ii < length; ++ii) - qlistPtr->append(engine->toQObject(array->Get(ii))); - } else { - qlistPtr->append(engine->toQObject(value)); - } - type = callType; - } else if (callType == qMetaTypeId<QDeclarativeV8Handle>()) { - handlePtr = new (&allocData) QDeclarativeV8Handle(QDeclarativeV8Handle::fromHandle(value)); - type = callType; - } else { - qvariantPtr = new (&allocData) QVariant(); - type = -1; - - QDeclarativeEnginePrivate *ep = engine->engine() ? QDeclarativeEnginePrivate::get(engine->engine()) : 0; - QVariant v = engine->toVariant(value, -1); - - if (v.userType() == callType) { - *qvariantPtr = v; - } else if (v.canConvert((QVariant::Type)callType)) { - *qvariantPtr = v; - qvariantPtr->convert((QVariant::Type)callType); - } else if (const QMetaObject *mo = ep ? ep->rawMetaObjectForType(callType) : 0) { - QObject *obj = ep->toQObject(v); - - if (obj) { - const QMetaObject *objMo = obj->metaObject(); - while (objMo && objMo != mo) objMo = objMo->superClass(); - if (!objMo) obj = 0; - } - - *qvariantPtr = QVariant(callType, &obj); - } else { - *qvariantPtr = QVariant(callType, (void *)0); - } - } -} - -v8::Handle<v8::Value> CallArgument::toValue(QV8Engine *engine) -{ - if (type == qMetaTypeId<QJSValue>()) { - return QJSValuePrivate::get(*qjsValuePtr)->asV8Value(engine); - } else if (type == QMetaType::Int) { - return v8::Integer::New(int(intValue)); - } else if (type == QMetaType::UInt) { - return v8::Integer::NewFromUnsigned(intValue); - } else if (type == QMetaType::Bool) { - return v8::Boolean::New(boolValue); - } else if (type == QMetaType::Double) { - return v8::Number::New(doubleValue); - } else if (type == QMetaType::Float) { - return v8::Number::New(floatValue); - } else if (type == QMetaType::QString) { - return engine->toString(*qstringPtr); - } else if (type == QMetaType::QObjectStar) { - QObject *object = qobjectPtr; - if (object) - QDeclarativeData::get(object, true)->setImplicitDestructible(); - return engine->newQObject(object); - } else if (type == qMetaTypeId<QList<QObject *> >()) { - // XXX Can this be made more by using Array as a prototype and implementing - // directly against QList<QObject*>? - QList<QObject *> &list = *qlistPtr; - v8::Local<v8::Array> array = v8::Array::New(list.count()); - for (int ii = 0; ii < list.count(); ++ii) - array->Set(ii, engine->newQObject(list.at(ii))); - return array; - } else if (type == qMetaTypeId<QDeclarativeV8Handle>()) { - return handlePtr->toHandle(); - } else if (type == -1 || type == qMetaTypeId<QVariant>()) { - QVariant value = *qvariantPtr; - v8::Handle<v8::Value> rv = engine->fromVariant(value); - if (QObject *object = engine->toQObject(rv)) - QDeclarativeData::get(object, true)->setImplicitDestructible(); - return rv; - } else { - return v8::Undefined(); - } -} - -QT_END_NAMESPACE - diff --git a/src/declarative/qml/v8/qv8qobjectwrapper_p.h b/src/declarative/qml/v8/qv8qobjectwrapper_p.h deleted file mode 100644 index c029285d08..0000000000 --- a/src/declarative/qml/v8/qv8qobjectwrapper_p.h +++ /dev/null @@ -1,159 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QV8QOBJECTWRAPPER_P_H -#define QV8QOBJECTWRAPPER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/qglobal.h> -#include <QtCore/qmetatype.h> -#include <QtCore/qpair.h> -#include <QtCore/qhash.h> -#include <private/qv8_p.h> -#include <private/qhashedstring_p.h> -#include <private/qdeclarativedata_p.h> -#include <private/qdeclarativepropertycache_p.h> - -QT_BEGIN_NAMESPACE - -class QObject; -class QV8Engine; -class QDeclarativeData; -class QV8ObjectResource; -class QV8QObjectInstance; -class QV8QObjectConnectionList; -class QDeclarativePropertyCache; -class Q_DECLARATIVE_EXPORT QV8QObjectWrapper -{ -public: - QV8QObjectWrapper(); - ~QV8QObjectWrapper(); - - void init(QV8Engine *); - void destroy(); - - v8::Handle<v8::Value> newQObject(QObject *object); - bool isQObject(v8::Handle<v8::Object>); - QObject *toQObject(v8::Handle<v8::Object>); - static QObject *toQObject(QV8ObjectResource *); - - enum RevisionMode { IgnoreRevision, CheckRevision }; - inline v8::Handle<v8::Value> getProperty(QObject *, const QHashedV8String &, RevisionMode); - inline bool setProperty(QObject *, const QHashedV8String &, v8::Handle<v8::Value>, RevisionMode); - -private: - friend class QDeclarativePropertyCache; - friend class QV8QObjectConnectionList; - friend class QV8QObjectInstance; - - v8::Local<v8::Object> newQObject(QObject *, QDeclarativeData *, QV8Engine *); - static v8::Handle<v8::Value> GetProperty(QV8Engine *, QObject *, v8::Handle<v8::Value> *, - const QHashedV8String &, QV8QObjectWrapper::RevisionMode); - static bool SetProperty(QV8Engine *, QObject *, const QHashedV8String &, - v8::Handle<v8::Value>, QV8QObjectWrapper::RevisionMode); - static v8::Handle<v8::Value> Getter(v8::Local<v8::String> property, - const v8::AccessorInfo &info); - static v8::Handle<v8::Value> Setter(v8::Local<v8::String> property, - v8::Local<v8::Value> value, - const v8::AccessorInfo &info); - static v8::Handle<v8::Integer> Query(v8::Local<v8::String> property, - const v8::AccessorInfo &info); - static v8::Handle<v8::Array> Enumerator(const v8::AccessorInfo &info); - static v8::Handle<v8::Value> Connect(const v8::Arguments &args); - static v8::Handle<v8::Value> Disconnect(const v8::Arguments &args); - static v8::Handle<v8::Value> Invoke(const v8::Arguments &args); - static QPair<QObject *, int> ExtractQtMethod(QV8Engine *, v8::Handle<v8::Function>); - static QPair<QObject *, int> ExtractQtSignal(QV8Engine *, v8::Handle<v8::Object>); - - QV8Engine *m_engine; - quint32 m_id; - v8::Persistent<v8::Function> m_constructor; - v8::Persistent<v8::Function> m_methodConstructor; - v8::Persistent<v8::Function> m_signalHandlerConstructor; - v8::Persistent<v8::String> m_toStringSymbol; - v8::Persistent<v8::String> m_destroySymbol; - QHashedV8String m_toStringString; - QHashedV8String m_destroyString; - v8::Persistent<v8::Object> m_hiddenObject; - QHash<QObject *, QV8QObjectConnectionList *> m_connections; - typedef QHash<QObject *, QV8QObjectInstance *> TaintedHash; - TaintedHash m_taintedObjects; -}; - -v8::Handle<v8::Value> QV8QObjectWrapper::getProperty(QObject *object, const QHashedV8String &string, - RevisionMode mode) -{ - QDeclarativeData *dd = QDeclarativeData::get(object, false); - if (!dd || !dd->propertyCache || m_toStringString == string || m_destroyString == string || - dd->propertyCache->property(string)) { - return GetProperty(m_engine, object, 0, string, mode); - } else { - return v8::Handle<v8::Value>(); - } -} - -bool QV8QObjectWrapper::setProperty(QObject *object, const QHashedV8String &string, - v8::Handle<v8::Value> value, RevisionMode mode) -{ - QDeclarativeData *dd = QDeclarativeData::get(object, false); - if (!dd || !dd->propertyCache || m_toStringString == string || m_destroyString == string || - dd->propertyCache->property(string)) { - return SetProperty(m_engine, object, string, value, mode); - } else { - return false; - } -} - -QT_END_NAMESPACE - -#endif // QV8QOBJECTWRAPPER_P_H - - diff --git a/src/declarative/qml/v8/qv8sequencewrapper.cpp b/src/declarative/qml/v8/qv8sequencewrapper.cpp deleted file mode 100644 index 7d7184e83d..0000000000 --- a/src/declarative/qml/v8/qv8sequencewrapper.cpp +++ /dev/null @@ -1,264 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtDeclarative/qdeclarative.h> - -#include "qv8sequencewrapper_p.h" -#include "qv8sequencewrapper_p_p.h" -#include "qv8engine_p.h" - -QT_BEGIN_NAMESPACE - -QV8SequenceWrapper::QV8SequenceWrapper() - : m_engine(0) -{ -} - -QV8SequenceWrapper::~QV8SequenceWrapper() -{ -} - -#define REGISTER_QML_SEQUENCE_METATYPE(unused, unused2, SequenceType, unused3) qRegisterMetaType<SequenceType>(); -void QV8SequenceWrapper::init(QV8Engine *engine) -{ - FOREACH_QML_SEQUENCE_TYPE(REGISTER_QML_SEQUENCE_METATYPE) - - m_engine = engine; - m_toString = qPersistentNew<v8::Function>(v8::FunctionTemplate::New(ToString)->GetFunction()); - m_valueOf = qPersistentNew<v8::Function>(v8::FunctionTemplate::New(ValueOf)->GetFunction()); - v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New(); - ft->InstanceTemplate()->SetFallbackPropertyHandler(Getter, Setter); - ft->InstanceTemplate()->SetIndexedPropertyHandler(IndexedGetter, IndexedSetter, 0, IndexedDeleter, IndexedEnumerator); - ft->InstanceTemplate()->SetAccessor(v8::String::New("length"), LengthGetter, LengthSetter, - v8::Handle<v8::Value>(), v8::DEFAULT, - v8::PropertyAttribute(v8::DontDelete | v8::DontEnum)); - ft->InstanceTemplate()->SetAccessor(v8::String::New("toString"), ToStringGetter, 0, - m_toString, v8::DEFAULT, - v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete | v8::DontEnum)); - ft->InstanceTemplate()->SetAccessor(v8::String::New("valueOf"), ValueOfGetter, 0, - m_valueOf, v8::DEFAULT, - v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete | v8::DontEnum)); - ft->InstanceTemplate()->SetHasExternalResource(true); - ft->InstanceTemplate()->MarkAsUseUserObjectComparison(); - m_constructor = qPersistentNew<v8::Function>(ft->GetFunction()); -} -#undef REGISTER_QML_SEQUENCE_METATYPE - -void QV8SequenceWrapper::destroy() -{ - qPersistentDispose(m_toString); - qPersistentDispose(m_valueOf); - qPersistentDispose(m_constructor); -} - -bool QV8SequenceWrapper::isEqual(QV8ObjectResource *lhs, QV8ObjectResource *rhs) -{ - Q_ASSERT(lhs && rhs && lhs->resourceType() == QV8ObjectResource::SequenceType && rhs->resourceType() == QV8ObjectResource::SequenceType); - QV8SequenceResource *lr = static_cast<QV8SequenceResource *>(lhs); - QV8SequenceResource *rr = static_cast<QV8SequenceResource *>(rhs); - return lr->isEqual(rr); -} - -quint32 QV8SequenceWrapper::sequenceLength(QV8ObjectResource *r) -{ - Q_ASSERT(r->resourceType() == QV8ObjectResource::SequenceType); - QV8SequenceResource *sr = static_cast<QV8SequenceResource *>(r); - Q_ASSERT(sr); - return sr->lengthGetter(); -} - -#define NEW_REFERENCE_SEQUENCE(ElementType, ElementTypeName, SequenceType, unused) \ - if (sequenceType == qMetaTypeId<SequenceType>()) { \ - r = new QV8##ElementTypeName##SequenceResource(m_engine, object, propertyIndex); \ - } else - -v8::Local<v8::Object> QV8SequenceWrapper::newSequence(int sequenceType, QObject *object, int propertyIndex, bool *succeeded) -{ - // This function is called when the property is a QObject Q_PROPERTY of - // the given sequence type. Internally we store a typed-sequence - // (as well as object ptr + property index for updated-read and write-back) - // and so access/mutate avoids variant conversion. - *succeeded = true; - QV8SequenceResource *r = 0; - FOREACH_QML_SEQUENCE_TYPE(NEW_REFERENCE_SEQUENCE) { /* else */ *succeeded = false; return v8::Local<v8::Object>(); } - - v8::Local<v8::Object> rv = m_constructor->NewInstance(); - rv->SetExternalResource(r); - rv->SetPrototype(v8::Array::New(1)->GetPrototype()); - return rv; -} -#undef NEW_REFERENCE_SEQUENCE - -#define NEW_COPY_SEQUENCE(ElementType, ElementTypeName, SequenceType, unused) \ - if (sequenceType == qMetaTypeId<SequenceType>()) { \ - r = new QV8##ElementTypeName##SequenceResource(m_engine, v.value<SequenceType>()); \ - } else - -v8::Local<v8::Object> QV8SequenceWrapper::fromVariant(const QVariant& v, bool *succeeded) -{ - // This function is called when assigning a sequence value to a normal JS var - // in a JS block. Internally, we store a sequence of the specified type. - // Access and mutation is extremely fast since it will not need to modify any - // QObject property. - int sequenceType = v.userType(); - *succeeded = true; - QV8SequenceResource *r = 0; - FOREACH_QML_SEQUENCE_TYPE(NEW_COPY_SEQUENCE) { /* else */ *succeeded = false; return v8::Local<v8::Object>(); } - - v8::Local<v8::Object> rv = m_constructor->NewInstance(); - rv->SetExternalResource(r); - rv->SetPrototype(v8::Array::New(1)->GetPrototype()); - return rv; -} -#undef NEW_COPY_SEQUENCE - -QVariant QV8SequenceWrapper::toVariant(QV8ObjectResource *r) -{ - Q_ASSERT(r->resourceType() == QV8ObjectResource::SequenceType); - QV8SequenceResource *resource = static_cast<QV8SequenceResource *>(r); - return resource->toVariant(); -} - -#define SEQUENCE_TO_VARIANT(ElementType, ElementTypeName, SequenceType, unused) \ - if (typeHint == qMetaTypeId<SequenceType>()) { \ - return QV8##ElementTypeName##SequenceResource::toVariant(m_engine, array, length, succeeded); \ - } else - -QVariant QV8SequenceWrapper::toVariant(v8::Handle<v8::Array> array, int typeHint, bool *succeeded) -{ - *succeeded = true; - uint32_t length = array->Length(); - FOREACH_QML_SEQUENCE_TYPE(SEQUENCE_TO_VARIANT) { /* else */ *succeeded = false; return QVariant(); } -} -#undef SEQUENCE_TO_VARIANT - -v8::Handle<v8::Value> QV8SequenceWrapper::IndexedSetter(quint32 index, v8::Local<v8::Value> value, const v8::AccessorInfo &info) -{ - QV8SequenceResource *sr = v8_resource_cast<QV8SequenceResource>(info.This()); - Q_ASSERT(sr); - return sr->indexedSetter(index, value); -} - -v8::Handle<v8::Value> QV8SequenceWrapper::IndexedGetter(quint32 index, const v8::AccessorInfo &info) -{ - QV8SequenceResource *sr = v8_resource_cast<QV8SequenceResource>(info.This()); - Q_ASSERT(sr); - return sr->indexedGetter(index); -} - -v8::Handle<v8::Boolean> QV8SequenceWrapper::IndexedDeleter(quint32 index, const v8::AccessorInfo &info) -{ - QV8SequenceResource *sr = v8_resource_cast<QV8SequenceResource>(info.This()); - Q_ASSERT(sr); - return sr->indexedDeleter(index); -} - -v8::Handle<v8::Array> QV8SequenceWrapper::IndexedEnumerator(const v8::AccessorInfo &info) -{ - QV8SequenceResource *sr = v8_resource_cast<QV8SequenceResource>(info.This()); - Q_ASSERT(sr); - return sr->indexedEnumerator(); -} - -v8::Handle<v8::Value> QV8SequenceWrapper::LengthGetter(v8::Local<v8::String> property, const v8::AccessorInfo &info) -{ - Q_UNUSED(property); - QV8SequenceResource *sr = v8_resource_cast<QV8SequenceResource>(info.This()); - Q_ASSERT(sr); - return v8::Integer::NewFromUnsigned(sr->lengthGetter()); -} - -void QV8SequenceWrapper::LengthSetter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo &info) -{ - Q_UNUSED(property); - QV8SequenceResource *sr = v8_resource_cast<QV8SequenceResource>(info.This()); - Q_ASSERT(sr); - sr->lengthSetter(value); -} - -v8::Handle<v8::Value> QV8SequenceWrapper::ToStringGetter(v8::Local<v8::String> property, const v8::AccessorInfo &info) -{ - Q_UNUSED(property); - return info.Data(); -} - -v8::Handle<v8::Value> QV8SequenceWrapper::ValueOfGetter(v8::Local<v8::String> property, - const v8::AccessorInfo &info) -{ - Q_UNUSED(property); - return info.Data(); -} - -v8::Handle<v8::Value> QV8SequenceWrapper::ToString(const v8::Arguments &args) -{ - QV8SequenceResource *sr = v8_resource_cast<QV8SequenceResource>(args.This()); - Q_ASSERT(sr); - return sr->toString(); -} - -v8::Handle<v8::Value> QV8SequenceWrapper::ValueOf(const v8::Arguments &args) -{ - QV8SequenceResource *sr = v8_resource_cast<QV8SequenceResource>(args.This()); - Q_ASSERT(sr); - v8::Handle<v8::Value> tostringValue = sr->toString(); - if (!tostringValue.IsEmpty()) - return tostringValue; - return v8::Integer::NewFromUnsigned(sr->lengthGetter()); -} - -v8::Handle<v8::Value> QV8SequenceWrapper::Getter(v8::Local<v8::String> property, - const v8::AccessorInfo &info) -{ - Q_UNUSED(property); - Q_UNUSED(info); - return v8::Handle<v8::Value>(); -} - -v8::Handle<v8::Value> QV8SequenceWrapper::Setter(v8::Local<v8::String> property, - v8::Local<v8::Value> value, - const v8::AccessorInfo &info) -{ - Q_UNUSED(property); - Q_UNUSED(info); - return value; -} - -QT_END_NAMESPACE diff --git a/src/declarative/qml/v8/qv8sequencewrapper_p.h b/src/declarative/qml/v8/qv8sequencewrapper_p.h deleted file mode 100644 index fae21d0b88..0000000000 --- a/src/declarative/qml/v8/qv8sequencewrapper_p.h +++ /dev/null @@ -1,106 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QV8SEQUENCEWRAPPER_P_H -#define QV8SEQUENCEWRAPPER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/qglobal.h> -#include <QtCore/qvariant.h> -#include <private/qv8_p.h> - -QT_BEGIN_NAMESPACE - -class QV8Engine; -class QV8ObjectResource; -class QV8SequenceWrapper -{ -public: - QV8SequenceWrapper(); - ~QV8SequenceWrapper(); - - void init(QV8Engine *); - void destroy(); - - bool isEqual(QV8ObjectResource *lhs, const QVariant &rhs); - bool isEqual(QV8ObjectResource *lhs, QV8ObjectResource *rhs); - quint32 sequenceLength(QV8ObjectResource *); - - v8::Local<v8::Object> newSequence(int sequenceTypeId, QObject *object, int propertyIndex, bool *succeeded); - v8::Local<v8::Object> fromVariant(const QVariant& v, bool *succeeded); - QVariant toVariant(QV8ObjectResource *); - QVariant toVariant(v8::Handle<v8::Array> array, int typeHint, bool *succeeded); - -private: - QV8Engine *m_engine; - - v8::Persistent<v8::Function> m_constructor; - v8::Persistent<v8::Function> m_toString; - v8::Persistent<v8::Function> m_valueOf; - - static v8::Handle<v8::Value> IndexedGetter(quint32 index, const v8::AccessorInfo &info); - static v8::Handle<v8::Value> IndexedSetter(quint32 index, v8::Local<v8::Value> value, const v8::AccessorInfo &info); - static v8::Handle<v8::Boolean> IndexedDeleter(quint32 index, const v8::AccessorInfo &info); - static v8::Handle<v8::Array> IndexedEnumerator(const v8::AccessorInfo &info); - static v8::Handle<v8::Value> LengthGetter(v8::Local<v8::String> property, const v8::AccessorInfo &info); - static void LengthSetter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo &info); - static v8::Handle<v8::Value> ToStringGetter(v8::Local<v8::String> property, const v8::AccessorInfo &info); - static v8::Handle<v8::Value> ToString(const v8::Arguments &args); - static v8::Handle<v8::Value> ValueOfGetter(v8::Local<v8::String> property, const v8::AccessorInfo &info); - static v8::Handle<v8::Value> ValueOf(const v8::Arguments &args); - static v8::Handle<v8::Value> Getter(v8::Local<v8::String> property, const v8::AccessorInfo &info); - static v8::Handle<v8::Value> Setter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo &info); -}; - - -QT_END_NAMESPACE - -#endif // QV8SEQUENCEWRAPPER_P_H diff --git a/src/declarative/qml/v8/qv8sequencewrapper_p_p.h b/src/declarative/qml/v8/qv8sequencewrapper_p_p.h deleted file mode 100644 index 41cdcaa8b7..0000000000 --- a/src/declarative/qml/v8/qv8sequencewrapper_p_p.h +++ /dev/null @@ -1,503 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QV8SEQUENCEWRAPPER_P_P_H -#define QV8SEQUENCEWRAPPER_P_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <private/qdeclarativeengine_p.h> -#include <private/qdeclarativemetatype_p.h> - -QT_BEGIN_NAMESPACE - -/*! - \internal - \class QV8SequenceResource - \brief The abstract base class of the external resource used in sequence type objects - - Every sequence type object returned by QV8SequenceWrapper::fromVariant() or - QV8SequenceWrapper::newSequence() has a type-specific QV8SequenceResource which - contains the type name, the meta type ids of the sequence and sequence element - types, as well as either the sequence data (copy) or object pointer and property - index (reference) data associated with the sequence. - */ -class QV8SequenceResource : public QV8ObjectResource -{ - V8_RESOURCE_TYPE(SequenceType); - -public: - virtual ~QV8SequenceResource() {} - - enum ObjectType { Reference, Copy }; - - virtual QVariant toVariant() = 0; - virtual bool isEqual(const QV8SequenceResource *v) = 0; - - virtual quint32 lengthGetter() = 0; - virtual void lengthSetter(v8::Handle<v8::Value> value) = 0; - virtual v8::Handle<v8::Value> indexedSetter(quint32 index, v8::Handle<v8::Value> value) = 0; - virtual v8::Handle<v8::Value> indexedGetter(quint32 index) = 0; - virtual v8::Handle<v8::Boolean> indexedDeleter(quint32 index) = 0; - virtual v8::Handle<v8::Array> indexedEnumerator() = 0; - virtual v8::Handle<v8::Value> toString() = 0; - - ObjectType objectType; - QByteArray typeName; - int sequenceMetaTypeId; - int elementMetaTypeId; - -protected: - QV8SequenceResource(QV8Engine *engine, ObjectType type, const QByteArray &name, int sequenceId, int elementId) - : QV8ObjectResource(engine), objectType(type), typeName(name), sequenceMetaTypeId(sequenceId), elementMetaTypeId(elementId) - { - } -}; - -// helper function to generate valid warnings if errors occur during sequence operations. -static void generateWarning(QV8Engine *engine, const QString& description) -{ - if (!engine) - return; - v8::Local<v8::StackTrace> currStack = v8::StackTrace::CurrentStackTrace(1); - if (currStack.IsEmpty()) - return; - v8::Local<v8::StackFrame> currFrame = currStack->GetFrame(0); - if (currFrame.IsEmpty()) - return; - - QDeclarativeError retn; - retn.setDescription(description); - retn.setLine(currFrame->GetLineNumber()); - retn.setUrl(QUrl(engine->toString(currFrame->GetScriptName()))); - QDeclarativeEnginePrivate::warning(engine->engine(), retn); -} - - -static int convertV8ValueToInt(QV8Engine *, v8::Handle<v8::Value> v) -{ - return v->Int32Value(); -} - -static v8::Handle<v8::Value> convertIntToV8Value(QV8Engine *, int v) -{ - return v8::Integer::New(v); -} - -static QString convertIntToString(QV8Engine *, int v) -{ - return QString::number(v); -} - -static qreal convertV8ValueToReal(QV8Engine *, v8::Handle<v8::Value> v) -{ - return v->NumberValue(); -} - -static v8::Handle<v8::Value> convertRealToV8Value(QV8Engine *, qreal v) -{ - return v8::Number::New(v); -} - -static QString convertRealToString(QV8Engine *, qreal v) -{ - return QString::number(v); -} - -static bool convertV8ValueToBool(QV8Engine *, v8::Handle<v8::Value> v) -{ - return v->BooleanValue(); -} - -static v8::Handle<v8::Value> convertBoolToV8Value(QV8Engine *, bool v) -{ - return v8::Boolean::New(v); -} - -static QString convertBoolToString(QV8Engine *, bool v) -{ - if (v) - return QLatin1String("true"); - return QLatin1String("false"); -} - -static QString convertV8ValueToString(QV8Engine *e, v8::Handle<v8::Value> v) -{ - return e->toString(v->ToString()); -} - -static v8::Handle<v8::Value> convertStringToV8Value(QV8Engine *e, const QString &v) -{ - return e->toString(v); -} - -static QString convertStringToString(QV8Engine *, const QString &v) -{ - return v; -} - -static QString convertV8ValueToQString(QV8Engine *e, v8::Handle<v8::Value> v) -{ - return e->toString(v->ToString()); -} - -static v8::Handle<v8::Value> convertQStringToV8Value(QV8Engine *e, const QString &v) -{ - return e->toString(v); -} - -static QString convertQStringToString(QV8Engine *, const QString &v) -{ - return v; -} - -static QUrl convertV8ValueToUrl(QV8Engine *e, v8::Handle<v8::Value> v) -{ - QUrl u; - u.setEncodedUrl(e->toString(v->ToString()).toUtf8(), QUrl::TolerantMode); - return u; -} - -static v8::Handle<v8::Value> convertUrlToV8Value(QV8Engine *e, const QUrl &v) -{ - return e->toString(QLatin1String(v.toEncoded().data())); -} - -static QString convertUrlToString(QV8Engine *, const QUrl &v) -{ - return v.toString(); -} - - -/* - \internal - \class QV8<Type>SequenceResource - \brief The external resource used in sequence type objects - - Every sequence type object returned by QV8SequenceWrapper::newSequence() has - a QV8<Type>SequenceResource which contains a property index and a pointer - to the object which contains the property. - - Every sequence type object returned by QV8SequenceWrapper::fromVariant() has - a QV8<Type>SequenceResource which contains a copy of the sequence value. - Operations on the sequence are implemented directly in terms of that sequence data. - - There exists one QV8<Type>SequenceResource instance for every JavaScript Object - (sequence) instance returned from QV8SequenceWrapper::newSequence() or - QV8SequenceWrapper::fromVariant(). - */ - -// F(elementType, elementTypeName, sequenceType, defaultValue) -#define FOREACH_QML_SEQUENCE_TYPE(F) \ - F(int, Int, QList<int>, 0) \ - F(qreal, Real, QList<qreal>, 0.0) \ - F(bool, Bool, QList<bool>, false) \ - F(QString, String, QList<QString>, QString()) \ - F(QString, QString, QStringList, QString()) \ - F(QUrl, Url, QList<QUrl>, QUrl()) - -#define QML_SEQUENCE_TYPE_RESOURCE(SequenceElementType, SequenceElementTypeName, SequenceType, DefaultValue, ConversionToV8fn, ConversionFromV8fn, ToStringfn) \ - QT_END_NAMESPACE \ - Q_DECLARE_METATYPE(SequenceType) \ - QT_BEGIN_NAMESPACE \ - class QV8##SequenceElementTypeName##SequenceResource : public QV8SequenceResource { \ - public:\ - QV8##SequenceElementTypeName##SequenceResource(QV8Engine *engine, QObject *obj, int propIdx) \ - : QV8SequenceResource(engine, QV8SequenceResource::Reference, #SequenceType, qMetaTypeId<SequenceType>(), qMetaTypeId<SequenceElementType>()) \ - , object(obj), propertyIndex(propIdx) \ - { \ - } \ - QV8##SequenceElementTypeName##SequenceResource(QV8Engine *engine, const SequenceType &value) \ - : QV8SequenceResource(engine, QV8SequenceResource::Copy, #SequenceType, qMetaTypeId<SequenceType>(), qMetaTypeId<SequenceElementType>()) \ - , object(0), propertyIndex(-1), c(value) \ - { \ - } \ - ~QV8##SequenceElementTypeName##SequenceResource() \ - { \ - } \ - static QVariant toVariant(QV8Engine *e, v8::Handle<v8::Array> array, uint32_t length, bool *succeeded) \ - { \ - SequenceType list; \ - for (uint32_t ii = 0; ii < length; ++ii) { \ - list.append(ConversionFromV8fn(e, array->Get(ii))); \ - } \ - *succeeded = true; \ - return QVariant::fromValue<SequenceType>(list); \ - } \ - QVariant toVariant() \ - { \ - if (objectType == QV8SequenceResource::Reference) { \ - if (!object) \ - return QVariant(); \ - loadReference(); \ - } \ - return QVariant::fromValue<SequenceType>(c); \ - } \ - bool isEqual(const QV8SequenceResource *v) \ - { \ - /* Note: two different sequences can never be equal (even if they */ \ - /* contain the same elements in the same order) in order to */ \ - /* maintain JavaScript semantics. However, if they both reference */ \ - /* the same QObject+propertyIndex, they are equal. */ \ - if (objectType == QV8SequenceResource::Reference && v->objectType == QV8SequenceResource::Reference) { \ - if (sequenceMetaTypeId == v->sequenceMetaTypeId) { \ - const QV8##SequenceElementTypeName##SequenceResource *rhs = static_cast<const QV8##SequenceElementTypeName##SequenceResource *>(v); \ - return (object != 0 && object == rhs->object && propertyIndex == rhs->propertyIndex); \ - } \ - } else if (objectType == QV8SequenceResource::Copy && v->objectType == QV8SequenceResource::Copy) { \ - if (sequenceMetaTypeId == v->sequenceMetaTypeId) { \ - const QV8##SequenceElementTypeName##SequenceResource *rhs = static_cast<const QV8##SequenceElementTypeName##SequenceResource *>(v); \ - return (this == rhs); \ - } \ - } \ - return false; \ - } \ - quint32 lengthGetter() \ - { \ - if (objectType == QV8SequenceResource::Reference) { \ - if (!object) \ - return 0; \ - loadReference(); \ - } \ - return static_cast<quint32>(c.count()); \ - } \ - void lengthSetter(v8::Handle<v8::Value> value) \ - { \ - /* Get the new required length */ \ - if (value.IsEmpty() || !value->IsUint32()) \ - return; \ - quint32 newLength = value->Uint32Value(); \ - /* Qt containers have int (rather than uint) allowable indexes. */ \ - if (newLength > INT_MAX) { \ - generateWarning(engine, QLatin1String("Index out of range during length set")); \ - return; \ - } \ - /* Read the sequence from the QObject property if we're a reference */ \ - if (objectType == QV8SequenceResource::Reference) { \ - if (!object) \ - return; \ - loadReference(); \ - } \ - /* Determine whether we need to modify the sequence */ \ - qint32 newCount = static_cast<qint32>(newLength); \ - qint32 count = c.count(); \ - if (newCount == count) { \ - return; \ - } else if (newCount > count) { \ - /* according to ECMA262r3 we need to insert */ \ - /* undefined values increasing length to newLength. */ \ - /* We cannot, so we insert default-values instead. */ \ - while (newCount > count++) { \ - QT_TRY { \ - c.append(DefaultValue); \ - } QT_CATCH (std::bad_alloc &exception) { \ - generateWarning(engine, QString(QLatin1String(exception.what()) \ - + QLatin1String(" during length set"))); \ - return; /* failed; don't write back any result. */ \ - } \ - } \ - } else { \ - /* according to ECMA262r3 we need to remove */ \ - /* elements until the sequence is the required length. */ \ - while (newCount < count) { \ - count--; \ - c.removeAt(count); \ - } \ - } \ - /* write back if required. */ \ - if (objectType == QV8SequenceResource::Reference) { \ - /* write back. already checked that object is non-null, so skip that check here. */ \ - storeReference(); \ - } \ - return; \ - } \ - v8::Handle<v8::Value> indexedSetter(quint32 index, v8::Handle<v8::Value> value) \ - { \ - /* Qt containers have int (rather than uint) allowable indexes. */ \ - if (index > INT_MAX) { \ - generateWarning(engine, QLatin1String("Index out of range during indexed set")); \ - return v8::Undefined(); \ - } \ - if (objectType == QV8SequenceResource::Reference) { \ - if (!object) \ - return v8::Undefined(); \ - loadReference(); \ - } \ - /* modify the sequence */ \ - SequenceElementType elementValue = ConversionFromV8fn(engine, value); \ - qint32 count = c.count(); \ - qint32 signedIdx = static_cast<qint32>(index); \ - if (signedIdx == count) { \ - c.append(elementValue); \ - } else if (signedIdx < count) { \ - c[index] = elementValue; \ - } else { \ - /* according to ECMA262r3 we need to insert */ \ - /* the value at the given index, increasing length to index+1. */ \ - QT_TRY { \ - while (signedIdx > count++) { \ - c.append(DefaultValue); \ - } \ - c.append(elementValue); \ - } QT_CATCH (std::bad_alloc &exception) { \ - generateWarning(engine, QString(QLatin1String(exception.what()) \ - + QLatin1String(" during indexed set"))); \ - return v8::Undefined(); /* failed; don't write back any result. */ \ - } \ - } \ - /* write back. already checked that object is non-null, so skip that check here. */ \ - if (objectType == QV8SequenceResource::Reference) \ - storeReference(); \ - return value; \ - } \ - v8::Handle<v8::Value> indexedGetter(quint32 index) \ - { \ - /* Qt containers have int (rather than uint) allowable indexes. */ \ - if (index > INT_MAX) { \ - generateWarning(engine, QLatin1String("Index out of range during indexed get")); \ - return v8::Undefined(); \ - } \ - if (objectType == QV8SequenceResource::Reference) { \ - if (!object) \ - return v8::Undefined(); \ - loadReference(); \ - } \ - qint32 count = c.count(); \ - qint32 signedIdx = static_cast<qint32>(index); \ - if (signedIdx < count) \ - return ConversionToV8fn(engine, c.at(signedIdx)); \ - return v8::Undefined(); \ - } \ - v8::Handle<v8::Boolean> indexedDeleter(quint32 index) \ - { \ - /* Qt containers have int (rather than uint) allowable indexes. */ \ - if (index > INT_MAX) \ - return v8::Boolean::New(false); \ - /* Read in the sequence from the QObject */ \ - if (objectType == QV8SequenceResource::Reference) { \ - if (!object) \ - return v8::Boolean::New(false); \ - loadReference(); \ - } \ - qint32 signedIdx = static_cast<qint32>(index); \ - if (signedIdx < c.count()) { \ - /* according to ECMA262r3 it should be Undefined, */ \ - /* but we cannot, so we insert a default-value instead. */ \ - c.replace(signedIdx, DefaultValue); \ - if (objectType == QV8SequenceResource::Reference) { \ - /* write back. already checked that object is non-null, so skip that check here. */ \ - storeReference(); \ - } \ - return v8::Boolean::New(true); \ - } \ - return v8::Boolean::New(false); \ - } \ - v8::Handle<v8::Array> indexedEnumerator() \ - { \ - if (objectType == QV8SequenceResource::Reference) { \ - if (!object) \ - return v8::Handle<v8::Array>(); \ - loadReference(); \ - } \ - qint32 count = c.count(); \ - v8::Local<v8::Array> retn = v8::Array::New(count); \ - for (qint32 i = 0; i < count; ++i) { \ - retn->Set(static_cast<quint32>(i), v8::Integer::NewFromUnsigned(static_cast<quint32>(i))); \ - } \ - return retn; \ - } \ - v8::Handle<v8::Value> toString() \ - { \ - if (objectType == QV8SequenceResource::Reference) { \ - if (!object) \ - return v8::Undefined(); \ - loadReference(); \ - } \ - QString str; \ - qint32 count = c.count(); \ - for (qint32 i = 0; i < count; ++i) { \ - str += QString(QLatin1String("%1,")).arg(ToStringfn(engine, c[i])); \ - } \ - str.chop(1); \ - return engine->toString(str); \ - } \ - void loadReference() \ - { \ - Q_ASSERT(object); \ - Q_ASSERT(objectType == QV8SequenceResource::Reference); \ - void *a[] = { &c, 0 }; \ - QMetaObject::metacall(object, QMetaObject::ReadProperty, propertyIndex, a); \ - } \ - void storeReference() \ - { \ - Q_ASSERT(object); \ - Q_ASSERT(objectType == QV8SequenceResource::Reference); \ - int status = -1; \ - QDeclarativePropertyPrivate::WriteFlags flags = \ - QDeclarativePropertyPrivate::DontRemoveBinding; \ - void *a[] = { &c, 0, &status, &flags }; \ - QMetaObject::metacall(object, QMetaObject::WriteProperty, propertyIndex, a); \ - } \ - private: \ - QDeclarativeGuard<QObject> object; \ - int propertyIndex; \ - SequenceType c; \ - }; - -#define GENERATE_QML_SEQUENCE_TYPE_RESOURCE(ElementType, ElementTypeName, SequenceType, DefaultValue) \ - QML_SEQUENCE_TYPE_RESOURCE(ElementType, ElementTypeName, SequenceType, DefaultValue, convert##ElementTypeName##ToV8Value, convertV8ValueTo##ElementTypeName, convert##ElementTypeName##ToString) - -FOREACH_QML_SEQUENCE_TYPE(GENERATE_QML_SEQUENCE_TYPE_RESOURCE) -#undef GENERATE_QML_SEQUENCE_TYPE_RESOURCE -#undef QML_SEQUENCE_TYPE_RESOURCE - -QT_END_NAMESPACE - -#endif // QV8SEQUENCEWRAPPER_P_P_H diff --git a/src/declarative/qml/v8/qv8sqlerrors.cpp b/src/declarative/qml/v8/qv8sqlerrors.cpp deleted file mode 100644 index f5e868650e..0000000000 --- a/src/declarative/qml/v8/qv8sqlerrors.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qv8sqlerrors_p.h" -#include "qv8engine_p.h" - -QT_BEGIN_NAMESPACE - -void qt_add_sqlexceptions(QV8Engine *engine) -{ - // SQL Exception - v8::PropertyAttribute attributes = (v8::PropertyAttribute)(v8::ReadOnly | v8::DontEnum | v8::DontDelete); - - v8::Local<v8::Object> sqlexception = v8::Object::New(); - sqlexception->Set(v8::String::New("UNKNOWN_ERR"), v8::Integer::New(SQLEXCEPTION_UNKNOWN_ERR), attributes); - sqlexception->Set(v8::String::New("DATABASE_ERR"), v8::Integer::New(SQLEXCEPTION_DATABASE_ERR), attributes); - sqlexception->Set(v8::String::New("VERSION_ERR"), v8::Integer::New(SQLEXCEPTION_VERSION_ERR), attributes); - sqlexception->Set(v8::String::New("TOO_LARGE_ERR"), v8::Integer::New(SQLEXCEPTION_TOO_LARGE_ERR), attributes); - sqlexception->Set(v8::String::New("QUOTA_ERR"), v8::Integer::New(SQLEXCEPTION_QUOTA_ERR), attributes); - sqlexception->Set(v8::String::New("SYNTAX_ERR"), v8::Integer::New(SQLEXCEPTION_SYNTAX_ERR), attributes); - sqlexception->Set(v8::String::New("CONSTRAINT_ERR"), v8::Integer::New(SQLEXCEPTION_CONSTRAINT_ERR), attributes); - sqlexception->Set(v8::String::New("TIMEOUT_ERR"), v8::Integer::New(SQLEXCEPTION_TIMEOUT_ERR), attributes); - engine->global()->Set(v8::String::New("SQLException"), sqlexception); -} - -QT_END_NAMESPACE diff --git a/src/declarative/qml/v8/qv8sqlerrors_p.h b/src/declarative/qml/v8/qv8sqlerrors_p.h deleted file mode 100644 index 8f4668cedd..0000000000 --- a/src/declarative/qml/v8/qv8sqlerrors_p.h +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QV8SQLERRORS_P_H -#define QV8SQLERRORS_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/qglobal.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE -#define SQLEXCEPTION_UNKNOWN_ERR 1 -#define SQLEXCEPTION_DATABASE_ERR 2 -#define SQLEXCEPTION_VERSION_ERR 3 -#define SQLEXCEPTION_TOO_LARGE_ERR 4 -#define SQLEXCEPTION_QUOTA_ERR 5 -#define SQLEXCEPTION_SYNTAX_ERR 6 -#define SQLEXCEPTION_CONSTRAINT_ERR 7 -#define SQLEXCEPTION_TIMEOUT_ERR 8 - -class QV8Engine; -void qt_add_sqlexceptions(QV8Engine *engine); - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QV8SQLERRORS_P_H diff --git a/src/declarative/qml/v8/qv8stringwrapper.cpp b/src/declarative/qml/v8/qv8stringwrapper.cpp deleted file mode 100644 index bff932150d..0000000000 --- a/src/declarative/qml/v8/qv8stringwrapper.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qv8stringwrapper_p.h" -#include "qjsconverter_p.h" -#include "qjsconverter_impl_p.h" - -QT_BEGIN_NAMESPACE - -QV8StringWrapper::QV8StringWrapper() -{ -} - -QV8StringWrapper::~QV8StringWrapper() -{ -} - -void QV8StringWrapper::init() -{ -} - -void QV8StringWrapper::destroy() -{ -} - -v8::Local<v8::String> QV8StringWrapper::toString(const QString &qstr) -{ - return QJSConverter::toString(qstr); -} - -QString QV8StringWrapper::toString(v8::Handle<v8::String> jsstr) -{ - if (jsstr.IsEmpty()) { - return QString(); - } else { - return QJSConverter::toString(jsstr); - } -} - -QT_END_NAMESPACE diff --git a/src/declarative/qml/v8/qv8stringwrapper_p.h b/src/declarative/qml/v8/qv8stringwrapper_p.h deleted file mode 100644 index 89fd5448d7..0000000000 --- a/src/declarative/qml/v8/qv8stringwrapper_p.h +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QDECLARATIVEV8STRINGWRAPPER_P_H -#define QDECLARATIVEV8STRINGWRAPPER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/qstring.h> -#include <private/qv8_p.h> - -QT_BEGIN_NAMESPACE - -class Q_DECLARATIVE_EXPORT QV8StringWrapper -{ -public: - QV8StringWrapper(); - ~QV8StringWrapper(); - - void init(); - void destroy(); - - v8::Local<v8::String> toString(const QString &); - QString toString(v8::Handle<v8::String>); -}; - -QT_END_NAMESPACE - -#endif // QDECLARATIVEV8STRINGWRAPPER_P_H diff --git a/src/declarative/qml/v8/qv8typewrapper.cpp b/src/declarative/qml/v8/qv8typewrapper.cpp deleted file mode 100644 index d9060be309..0000000000 --- a/src/declarative/qml/v8/qv8typewrapper.cpp +++ /dev/null @@ -1,314 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qv8contextwrapper_p.h" -#include "qv8engine_p.h" - -#include <private/qdeclarativeengine_p.h> -#include <private/qdeclarativecontext_p.h> - -#include <private/qjsvalue_p.h> -#include <private/qscript_impl_p.h> - -QT_BEGIN_NAMESPACE - -class QV8TypeResource : public QV8ObjectResource -{ - V8_RESOURCE_TYPE(TypeType); - -public: - QV8TypeResource(QV8Engine *engine); - virtual ~QV8TypeResource(); - - QV8TypeWrapper::TypeNameMode mode; - - QDeclarativeGuard<QObject> object; - - QDeclarativeType *type; - QDeclarativeTypeNameCache *typeNamespace; - const void *importNamespace; -}; - -QV8TypeResource::QV8TypeResource(QV8Engine *engine) -: QV8ObjectResource(engine), mode(QV8TypeWrapper::IncludeEnums), type(0), typeNamespace(0), importNamespace(0) -{ -} - -QV8TypeResource::~QV8TypeResource() -{ - if (typeNamespace) typeNamespace->release(); -} - -QV8TypeWrapper::QV8TypeWrapper() -: m_engine(0) -{ -} - -QV8TypeWrapper::~QV8TypeWrapper() -{ -} - -void QV8TypeWrapper::destroy() -{ - qPersistentDispose(m_constructor); -} - -void QV8TypeWrapper::init(QV8Engine *engine) -{ - m_engine = engine; - v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New(); - ft->InstanceTemplate()->SetNamedPropertyHandler(Getter, Setter); - ft->InstanceTemplate()->SetHasExternalResource(true); - m_constructor = qPersistentNew<v8::Function>(ft->GetFunction()); -} - -// Returns a type wrapper for type t on o. This allows access of enums, and attached properties. -v8::Local<v8::Object> QV8TypeWrapper::newObject(QObject *o, QDeclarativeType *t, TypeNameMode mode) -{ - Q_ASSERT(t); - // XXX NewInstance() should be optimized - v8::Local<v8::Object> rv = m_constructor->NewInstance(); - QV8TypeResource *r = new QV8TypeResource(m_engine); - r->mode = mode; r->object = o; r->type = t; - rv->SetExternalResource(r); - return rv; -} - -// Returns a type wrapper for importNamespace (of t) on o. This allows nested resolution of a type in a -// namespace. -v8::Local<v8::Object> QV8TypeWrapper::newObject(QObject *o, QDeclarativeTypeNameCache *t, - const void *importNamespace, TypeNameMode mode) -{ - Q_ASSERT(t); - Q_ASSERT(importNamespace); - // XXX NewInstance() should be optimized - v8::Local<v8::Object> rv = m_constructor->NewInstance(); - QV8TypeResource *r = new QV8TypeResource(m_engine); - t->addref(); - r->mode = mode; r->object = o; r->typeNamespace = t; r->importNamespace = importNamespace; - rv->SetExternalResource(r); - return rv; -} - -QVariant QV8TypeWrapper::toVariant(QV8ObjectResource *r) -{ - Q_ASSERT(r->resourceType() == QV8ObjectResource::TypeType); - QV8TypeResource *resource = static_cast<QV8TypeResource *>(r); - QV8Engine *v8engine = resource->engine; - - if (resource->typeNamespace) { - if (QDeclarativeMetaType::ModuleApiInstance *moduleApi = resource->typeNamespace->moduleApi(resource->importNamespace)) { - if (moduleApi->scriptCallback) { - moduleApi->scriptApi = moduleApi->scriptCallback(v8engine->engine(), v8engine->engine()); - moduleApi->scriptCallback = 0; - moduleApi->qobjectCallback = 0; - } else if (moduleApi->qobjectCallback) { - moduleApi->qobjectApi = moduleApi->qobjectCallback(v8engine->engine(), v8engine->engine()); - moduleApi->scriptCallback = 0; - moduleApi->qobjectCallback = 0; - } - - if (moduleApi->qobjectApi) { - return QVariant::fromValue<QObject*>(moduleApi->qobjectApi); - } - } - } - - // only QObject Module API can be converted to a variant. - return QVariant(); -} - -v8::Handle<v8::Value> QV8TypeWrapper::Getter(v8::Local<v8::String> property, - const v8::AccessorInfo &info) -{ - QV8TypeResource *resource = v8_resource_cast<QV8TypeResource>(info.This()); - - if (!resource) - return v8::Undefined(); - - QV8Engine *v8engine = resource->engine; - QObject *object = resource->object; - - QHashedV8String propertystring(property); - - if (resource->type) { - QDeclarativeType *type = resource->type; - - if (QV8Engine::startsWithUpper(property)) { - int value = type->enumValue(propertystring); - if (-1 != value) - return v8::Integer::New(value); - - // Fall through to return empty handle - - } else if (resource->object) { - QObject *ao = qmlAttachedPropertiesObjectById(type->attachedPropertiesId(), object); - if (ao) - return v8engine->qobjectWrapper()->getProperty(ao, propertystring, - QV8QObjectWrapper::IgnoreRevision); - - // Fall through to return empty handle - } - - // Fall through to return empty handle - - } else if (resource->typeNamespace) { - Q_ASSERT(resource->importNamespace); - QDeclarativeTypeNameCache::Result r = resource->typeNamespace->query(propertystring, - resource->importNamespace); - - if (r.isValid()) { - if (r.type) { - return v8engine->typeWrapper()->newObject(object, r.type, resource->mode); - } else if (r.scriptIndex != -1) { - int index = r.scriptIndex; - QDeclarativeContextData *context = v8engine->callingContext(); - if (index < context->importedScripts.count()) - return context->importedScripts.at(index); - } - - return v8::Undefined(); - } else if (QDeclarativeMetaType::ModuleApiInstance *moduleApi = resource->typeNamespace->moduleApi(resource->importNamespace)) { - - if (moduleApi->scriptCallback) { - moduleApi->scriptApi = moduleApi->scriptCallback(v8engine->engine(), v8engine->engine()); - moduleApi->scriptCallback = 0; - moduleApi->qobjectCallback = 0; - } else if (moduleApi->qobjectCallback) { - moduleApi->qobjectApi = moduleApi->qobjectCallback(v8engine->engine(), v8engine->engine()); - moduleApi->scriptCallback = 0; - moduleApi->qobjectCallback = 0; - } - - if (moduleApi->qobjectApi) { - // check for enum value - if (QV8Engine::startsWithUpper(property)) { - if (resource->mode == IncludeEnums) { - QString name = v8engine->toString(property); - - // ### Optimize - QByteArray enumName = name.toUtf8(); - const QMetaObject *metaObject = moduleApi->qobjectApi->metaObject(); - for (int ii = metaObject->enumeratorCount() - 1; ii >= 0; --ii) { - QMetaEnum e = metaObject->enumerator(ii); - bool ok; - int value = e.keyToValue(enumName.constData(), &ok); - if (ok) - return v8::Integer::New(value); - } - } - } - - // check for property. - v8::Handle<v8::Value> rv = v8engine->qobjectWrapper()->getProperty(moduleApi->qobjectApi, propertystring, QV8QObjectWrapper::IgnoreRevision); - return rv; - } else if (!moduleApi->scriptApi.isUndefined()) { - // NOTE: if used in a binding, changes will not trigger re-evaluation since non-NOTIFYable. - QJSValuePrivate *apiprivate = QJSValuePrivate::get(moduleApi->scriptApi); - QScopedPointer<QJSValuePrivate> propertyValue(apiprivate->property(property).give()); - return propertyValue->asV8Value(v8engine); - } else { - return v8::Handle<v8::Value>(); - } - } - - // Fall through to return empty handle - - } else { - Q_ASSERT(!"Unreachable"); - } - - return v8::Handle<v8::Value>(); -} - -v8::Handle<v8::Value> QV8TypeWrapper::Setter(v8::Local<v8::String> property, - v8::Local<v8::Value> value, - const v8::AccessorInfo &info) -{ - QV8TypeResource *resource = v8_resource_cast<QV8TypeResource>(info.This()); - - if (!resource) - return value; - - QV8Engine *v8engine = resource->engine; - - QHashedV8String propertystring(property); - - if (resource->type && resource->object) { - QDeclarativeType *type = resource->type; - QObject *object = resource->object; - QObject *ao = qmlAttachedPropertiesObjectById(type->attachedPropertiesId(), object); - if (ao) - v8engine->qobjectWrapper()->setProperty(ao, propertystring, value, - QV8QObjectWrapper::IgnoreRevision); - } else if (resource->typeNamespace) { - if (QDeclarativeMetaType::ModuleApiInstance *moduleApi = resource->typeNamespace->moduleApi(resource->importNamespace)) { - if (moduleApi->scriptCallback) { - moduleApi->scriptApi = moduleApi->scriptCallback(v8engine->engine(), v8engine->engine()); - moduleApi->scriptCallback = 0; - moduleApi->qobjectCallback = 0; - } else if (moduleApi->qobjectCallback) { - moduleApi->qobjectApi = moduleApi->qobjectCallback(v8engine->engine(), v8engine->engine()); - moduleApi->scriptCallback = 0; - moduleApi->qobjectCallback = 0; - } - - if (moduleApi->qobjectApi) { - v8engine->qobjectWrapper()->setProperty(moduleApi->qobjectApi, propertystring, value, - QV8QObjectWrapper::IgnoreRevision); - } else if (!moduleApi->scriptApi.isUndefined()) { - QScopedPointer<QJSValuePrivate> setvalp(new QJSValuePrivate(v8engine, value)); - QJSValuePrivate *apiprivate = QJSValuePrivate::get(moduleApi->scriptApi); - if (apiprivate->propertyFlags(property) & QJSValuePrivate::ReadOnly) { - 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()); - } - } - } - } - - return value; -} - -QT_END_NAMESPACE diff --git a/src/declarative/qml/v8/qv8typewrapper_p.h b/src/declarative/qml/v8/qv8typewrapper_p.h deleted file mode 100644 index d30dbfbc24..0000000000 --- a/src/declarative/qml/v8/qv8typewrapper_p.h +++ /dev/null @@ -1,94 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QV8TYPEWRAPPER_P_H -#define QV8TYPEWRAPPER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/qglobal.h> -#include <private/qv8_p.h> - -QT_BEGIN_NAMESPACE - -class QObject; -class QV8Engine; -class QDeclarativeType; -class QDeclarativeTypeNameCache; -class QV8TypeWrapper -{ -public: - QV8TypeWrapper(); - ~QV8TypeWrapper(); - - void init(QV8Engine *); - void destroy(); - - enum TypeNameMode { IncludeEnums, ExcludeEnums }; - v8::Local<v8::Object> newObject(QObject *, QDeclarativeType *, TypeNameMode = IncludeEnums); - v8::Local<v8::Object> newObject(QObject *, QDeclarativeTypeNameCache *, const void *, - TypeNameMode = IncludeEnums); - QVariant toVariant(QV8ObjectResource *); - -private: - static v8::Handle<v8::Value> Getter(v8::Local<v8::String> property, - const v8::AccessorInfo &info); - static v8::Handle<v8::Value> Setter(v8::Local<v8::String> property, - v8::Local<v8::Value> value, - const v8::AccessorInfo &info); - - QV8Engine *m_engine; - v8::Persistent<v8::Function> m_constructor; -}; - -QT_END_NAMESPACE - -#endif // QV8TYPEWRAPPER_P_H - diff --git a/src/declarative/qml/v8/qv8valuetypewrapper.cpp b/src/declarative/qml/v8/qv8valuetypewrapper.cpp deleted file mode 100644 index 7da3d8a2dc..0000000000 --- a/src/declarative/qml/v8/qv8valuetypewrapper.cpp +++ /dev/null @@ -1,387 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qv8valuetypewrapper_p.h" -#include "qv8engine_p.h" - -#include <private/qdeclarativevaluetype_p.h> -#include <private/qdeclarativebinding_p.h> - -QT_BEGIN_NAMESPACE - -class QV8ValueTypeResource : public QV8ObjectResource -{ - V8_RESOURCE_TYPE(ValueTypeType); - -public: - enum ObjectType { Reference, Copy }; - - QV8ValueTypeResource(QV8Engine *engine, ObjectType objectType); - - ObjectType objectType; - QDeclarativeValueType *type; -}; - -class QV8ValueTypeReferenceResource : public QV8ValueTypeResource -{ -public: - QV8ValueTypeReferenceResource(QV8Engine *engine); - - QDeclarativeGuard<QObject> object; - int property; -}; - -class QV8ValueTypeCopyResource : public QV8ValueTypeResource -{ -public: - QV8ValueTypeCopyResource(QV8Engine *engine); - - QVariant value; -}; - -QV8ValueTypeResource::QV8ValueTypeResource(QV8Engine *engine, ObjectType objectType) -: QV8ObjectResource(engine), objectType(objectType) -{ -} - -QV8ValueTypeReferenceResource::QV8ValueTypeReferenceResource(QV8Engine *engine) -: QV8ValueTypeResource(engine, Reference) -{ -} - -QV8ValueTypeCopyResource::QV8ValueTypeCopyResource(QV8Engine *engine) -: QV8ValueTypeResource(engine, Copy) -{ -} - -QV8ValueTypeWrapper::QV8ValueTypeWrapper() -: m_engine(0) -{ -} - -QV8ValueTypeWrapper::~QV8ValueTypeWrapper() -{ -} - -void QV8ValueTypeWrapper::destroy() -{ - qPersistentDispose(m_toString); - qPersistentDispose(m_constructor); - qPersistentDispose(m_toStringSymbol); -} - -static quint32 toStringHash = -1; - -void QV8ValueTypeWrapper::init(QV8Engine *engine) -{ - m_engine = engine; - m_toString = qPersistentNew<v8::Function>(v8::FunctionTemplate::New(ToString)->GetFunction()); - v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New(); - ft->InstanceTemplate()->SetNamedPropertyHandler(Getter, Setter); - ft->InstanceTemplate()->SetHasExternalResource(true); - ft->InstanceTemplate()->MarkAsUseUserObjectComparison(); - ft->InstanceTemplate()->SetAccessor(v8::String::New("toString"), ToStringGetter, 0, - m_toString, v8::DEFAULT, - v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete)); - m_constructor = qPersistentNew<v8::Function>(ft->GetFunction()); - - m_toStringSymbol = qPersistentNew<v8::String>(v8::String::NewSymbol("toString")); - m_toStringString = QHashedV8String(m_toStringSymbol); - toStringHash = m_toStringString.hash(); -} - -v8::Local<v8::Object> QV8ValueTypeWrapper::newValueType(QObject *object, int property, QDeclarativeValueType *type) -{ - // XXX NewInstance() should be optimized - v8::Local<v8::Object> rv = m_constructor->NewInstance(); - QV8ValueTypeReferenceResource *r = new QV8ValueTypeReferenceResource(m_engine); - r->type = type; r->object = object; r->property = property; - rv->SetExternalResource(r); - return rv; -} - -v8::Local<v8::Object> QV8ValueTypeWrapper::newValueType(const QVariant &value, QDeclarativeValueType *type) -{ - // XXX NewInstance() should be optimized - v8::Local<v8::Object> rv = m_constructor->NewInstance(); - QV8ValueTypeCopyResource *r = new QV8ValueTypeCopyResource(m_engine); - r->type = type; r->value = value; - rv->SetExternalResource(r); - return rv; -} - -QVariant QV8ValueTypeWrapper::toVariant(v8::Handle<v8::Object> obj) -{ - QV8ValueTypeResource *r = v8_resource_cast<QV8ValueTypeResource>(obj); - if (r) return toVariant(r); - else return QVariant(); -} - -QVariant QV8ValueTypeWrapper::toVariant(QV8ObjectResource *r) -{ - Q_ASSERT(r->resourceType() == QV8ObjectResource::ValueTypeType); - QV8ValueTypeResource *resource = static_cast<QV8ValueTypeResource *>(r); - - if (resource->objectType == QV8ValueTypeResource::Reference) { - QV8ValueTypeReferenceResource *reference = static_cast<QV8ValueTypeReferenceResource *>(resource); - - if (reference->object) { - reference->type->read(reference->object, reference->property); - return reference->type->value(); - } else { - return QVariant(); - } - - } else { - Q_ASSERT(resource->objectType == QV8ValueTypeResource::Copy); - - QV8ValueTypeCopyResource *copy = static_cast<QV8ValueTypeCopyResource *>(resource); - - return copy->value; - } -} - -bool QV8ValueTypeWrapper::isEqual(QV8ObjectResource *r, const QVariant& value) -{ - Q_ASSERT(r->resourceType() == QV8ObjectResource::ValueTypeType); - QV8ValueTypeResource *resource = static_cast<QV8ValueTypeResource *>(r); - - if (resource->objectType == QV8ValueTypeResource::Reference) { - QV8ValueTypeReferenceResource *reference = static_cast<QV8ValueTypeReferenceResource *>(resource); - if (reference->object) { - reference->type->read(reference->object, reference->property); - return reference->type->isEqual(value); - } else { - return false; - } - } else { - Q_ASSERT(resource->objectType == QV8ValueTypeResource::Copy); - QV8ValueTypeCopyResource *copy = static_cast<QV8ValueTypeCopyResource *>(resource); - return (value == copy->value); - } -} - -v8::Handle<v8::Value> QV8ValueTypeWrapper::ToStringGetter(v8::Local<v8::String> property, - const v8::AccessorInfo &info) -{ - Q_UNUSED(property); - return info.Data(); -} - -v8::Handle<v8::Value> QV8ValueTypeWrapper::ToString(const v8::Arguments &args) -{ - QV8ValueTypeResource *resource = v8_resource_cast<QV8ValueTypeResource>(args.This()); - if (resource) { - if (resource->objectType == QV8ValueTypeResource::Reference) { - QV8ValueTypeReferenceResource *reference = static_cast<QV8ValueTypeReferenceResource *>(resource); - if (reference->object) { - reference->type->read(reference->object, reference->property); - return resource->engine->toString(resource->type->toString()); - } else { - return v8::Undefined(); - } - } else { - Q_ASSERT(resource->objectType == QV8ValueTypeResource::Copy); - QV8ValueTypeCopyResource *copy = static_cast<QV8ValueTypeCopyResource *>(resource); - QString result = copy->value.toString(); - if (result.isEmpty() && !copy->value.canConvert(QVariant::String)) { - result = QString::fromLatin1("QVariant(%0)").arg(QString::fromLatin1(copy->value.typeName())); - } - return resource->engine->toString(result); - } - } else { - return v8::Undefined(); - } -} - -v8::Handle<v8::Value> QV8ValueTypeWrapper::Getter(v8::Local<v8::String> property, - const v8::AccessorInfo &info) -{ - QV8ValueTypeResource *r = v8_resource_cast<QV8ValueTypeResource>(info.This()); - if (!r) return v8::Handle<v8::Value>(); - - QHashedV8String propertystring(property); - - { - // Comparing the hash first actually makes a measurable difference here, at least on x86 - quint32 hash = propertystring.hash(); - if (hash == toStringHash && - r->engine->valueTypeWrapper()->m_toStringString == propertystring) { - return r->engine->valueTypeWrapper()->m_toString; - } - } - - QDeclarativePropertyData local; - QDeclarativePropertyData *result = 0; - { - QDeclarativeData *ddata = QDeclarativeData::get(r->type, false); - if (ddata && ddata->propertyCache) - result = ddata->propertyCache->property(propertystring); - else - result = QDeclarativePropertyCache::property(r->engine->engine(), r->type, - propertystring, local); - } - - if (!result) - return v8::Handle<v8::Value>(); - - if (r->objectType == QV8ValueTypeResource::Reference) { - QV8ValueTypeReferenceResource *reference = static_cast<QV8ValueTypeReferenceResource *>(r); - - if (!reference->object) - return v8::Handle<v8::Value>(); - - r->type->read(reference->object, reference->property); - } else { - Q_ASSERT(r->objectType == QV8ValueTypeResource::Copy); - - QV8ValueTypeCopyResource *copy = static_cast<QV8ValueTypeCopyResource *>(r); - - r->type->setValue(copy->value); - } - -#define VALUE_TYPE_LOAD(metatype, cpptype, constructor) \ - if (result->propType == metatype) { \ - cpptype v; \ - void *args[] = { &v, 0 }; \ - r->type->qt_metacall(QMetaObject::ReadProperty, result->coreIndex, args); \ - return constructor(v); \ - } - - // These four types are the most common used by the value type wrappers - VALUE_TYPE_LOAD(QMetaType::QReal, qreal, v8::Number::New); - VALUE_TYPE_LOAD(QMetaType::Int, int, v8::Integer::New); - VALUE_TYPE_LOAD(QMetaType::QString, QString, r->engine->toString); - VALUE_TYPE_LOAD(QMetaType::Bool, bool, v8::Boolean::New); - - QVariant v(result->propType, (void *)0); - void *args[] = { v.data(), 0 }; - r->type->qt_metacall(QMetaObject::ReadProperty, result->coreIndex, args); - return r->engine->fromVariant(v); -#undef VALUE_TYPE_ACCESSOR -} - -v8::Handle<v8::Value> QV8ValueTypeWrapper::Setter(v8::Local<v8::String> property, - v8::Local<v8::Value> value, - const v8::AccessorInfo &info) -{ - QV8ValueTypeResource *r = v8_resource_cast<QV8ValueTypeResource>(info.This()); - if (!r) return value; - - QByteArray propName = r->engine->toString(property).toUtf8(); - int index = r->type->metaObject()->indexOfProperty(propName.constData()); - if (index == -1) - return value; - - if (r->objectType == QV8ValueTypeResource::Reference) { - QV8ValueTypeReferenceResource *reference = static_cast<QV8ValueTypeReferenceResource *>(r); - - if (!reference->object || - !reference->object->metaObject()->property(reference->property).isWritable()) - return value; - - r->type->read(reference->object, reference->property); - QMetaProperty p = r->type->metaObject()->property(index); - - QDeclarativeBinding *newBinding = 0; - - if (value->IsFunction()) { - QDeclarativeContextData *context = r->engine->callingContext(); - v8::Handle<v8::Function> function = v8::Handle<v8::Function>::Cast(value); - - QDeclarativePropertyData cacheData; - cacheData.setFlags(QDeclarativePropertyData::IsWritable | - QDeclarativePropertyData::IsValueTypeVirtual); - cacheData.propType = reference->object->metaObject()->property(reference->property).userType(); - cacheData.coreIndex = reference->property; - cacheData.valueTypeFlags = 0; - cacheData.valueTypeCoreIndex = index; - cacheData.valueTypePropType = p.userType(); - - v8::Local<v8::StackTrace> trace = - v8::StackTrace::CurrentStackTrace(1, - (v8::StackTrace::StackTraceOptions)(v8::StackTrace::kLineNumber | - v8::StackTrace::kScriptName)); - v8::Local<v8::StackFrame> frame = trace->GetFrame(0); - int lineNumber = frame->GetLineNumber(); - int columnNumber = frame->GetColumn(); - QString url = r->engine->toString(frame->GetScriptName()); - - newBinding = new QDeclarativeBinding(&function, reference->object, context); - newBinding->setSourceLocation(url, lineNumber, columnNumber); - newBinding->setTarget(reference->object, cacheData, context); - newBinding->setEvaluateFlags(newBinding->evaluateFlags() | - QDeclarativeBinding::RequiresThisObject); - } - - QDeclarativeAbstractBinding *oldBinding = - QDeclarativePropertyPrivate::setBinding(reference->object, reference->property, index, newBinding); - if (oldBinding) - oldBinding->destroy(); - - if (!value->IsFunction()) { - QVariant v = r->engine->toVariant(value, -1); - - if (p.isEnumType() && (QMetaType::Type)v.type() == QMetaType::Double) - v = v.toInt(); - - p.write(reference->type, v); - - reference->type->write(reference->object, reference->property, 0); - } - - } else { - Q_ASSERT(r->objectType == QV8ValueTypeResource::Copy); - - QV8ValueTypeCopyResource *copy = static_cast<QV8ValueTypeCopyResource *>(r); - - QVariant v = r->engine->toVariant(value, -1); - - r->type->setValue(copy->value); - QMetaProperty p = r->type->metaObject()->property(index); - p.write(r->type, v); - copy->value = r->type->value(); - } - - return value; -} - -QT_END_NAMESPACE diff --git a/src/declarative/qml/v8/qv8valuetypewrapper_p.h b/src/declarative/qml/v8/qv8valuetypewrapper_p.h deleted file mode 100644 index 09f6e7def3..0000000000 --- a/src/declarative/qml/v8/qv8valuetypewrapper_p.h +++ /dev/null @@ -1,104 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QV8VALUETYPEWRAPPER_P_H -#define QV8VALUETYPEWRAPPER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/qglobal.h> -#include <QtDeclarative/qdeclarativelist.h> -#include <private/qv8_p.h> -#include <private/qhashedstring_p.h> - -QT_BEGIN_NAMESPACE - -class QV8Engine; -class QV8ObjectResource; -class QDeclarativeValueType; -class QV8ValueTypeWrapper -{ -public: - QV8ValueTypeWrapper(); - ~QV8ValueTypeWrapper(); - - void init(QV8Engine *); - void destroy(); - - v8::Local<v8::Object> newValueType(QObject *, int, QDeclarativeValueType *); - v8::Local<v8::Object> newValueType(const QVariant &, QDeclarativeValueType *); - - QVariant toVariant(v8::Handle<v8::Object>); - QVariant toVariant(QV8ObjectResource *); - - static bool isEqual(QV8ObjectResource *, const QVariant& value); - -private: - static v8::Handle<v8::Value> ToStringGetter(v8::Local<v8::String> property, - const v8::AccessorInfo &info); - static v8::Handle<v8::Value> ToString(const v8::Arguments &args); - static v8::Handle<v8::Value> Getter(v8::Local<v8::String> property, - const v8::AccessorInfo &info); - static v8::Handle<v8::Value> Setter(v8::Local<v8::String> property, - v8::Local<v8::Value> value, - const v8::AccessorInfo &info); - - QV8Engine *m_engine; - v8::Persistent<v8::Function> m_constructor; - v8::Persistent<v8::Function> m_toString; - v8::Persistent<v8::String> m_toStringSymbol; - QHashedV8String m_toStringString; -}; - -QT_END_NAMESPACE - -#endif // QV8VALUETYPEWRAPPER_P_H - - diff --git a/src/declarative/qml/v8/qv8variantresource_p.h b/src/declarative/qml/v8/qv8variantresource_p.h deleted file mode 100644 index dd8664ff15..0000000000 --- a/src/declarative/qml/v8/qv8variantresource_p.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QV8VARIANTRESOURCE_P_H -#define QV8VARIANTRESOURCE_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/qglobal.h> -#include <private/qv8_p.h> -#include <private/qv8engine_p.h> -#include <private/qdeclarativeengine_p.h> - -QT_BEGIN_NAMESPACE - -class QV8VariantResource : public QV8ObjectResource, - public QDeclarativeEnginePrivate::ScarceResourceData -{ - V8_RESOURCE_TYPE(VariantType) - -public: - QV8VariantResource(QV8Engine *engine, const QVariant &data); - - void addVmePropertyReference(); - void removeVmePropertyReference(); - - bool m_isScarceResource; - int m_vmePropertyReferenceCount; -}; - -QT_END_NAMESPACE - -#endif // QV8VARIANTRESOURCE_P_H - diff --git a/src/declarative/qml/v8/qv8variantwrapper.cpp b/src/declarative/qml/v8/qv8variantwrapper.cpp deleted file mode 100644 index cd9d09e451..0000000000 --- a/src/declarative/qml/v8/qv8variantwrapper.cpp +++ /dev/null @@ -1,279 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qv8variantwrapper_p.h" -#include "qv8variantresource_p.h" -#include "qv8engine_p.h" -#include <private/qdeclarativeengine_p.h> - -QT_BEGIN_NAMESPACE - -QV8VariantResource::QV8VariantResource(QV8Engine *engine, const QVariant &data) -: QV8ObjectResource(engine), QDeclarativeEnginePrivate::ScarceResourceData(data), m_isScarceResource(false), m_vmePropertyReferenceCount(0) -{ -} - -void QV8VariantResource::addVmePropertyReference() -{ - if (m_isScarceResource && ++m_vmePropertyReferenceCount == 1) { - // remove from the ep->scarceResources list - // since it is now no longer eligible to be - // released automatically by the engine. - node.remove(); - } -} - -void QV8VariantResource::removeVmePropertyReference() -{ - if (m_isScarceResource && --m_vmePropertyReferenceCount == 0) { - // and add to the ep->scarceResources list - // since it is now eligible to be released - // automatically by the engine. - QDeclarativeEnginePrivate::get(engine->engine())->scarceResources.insert(this); - } -} - -QV8VariantWrapper::QV8VariantWrapper() -: m_engine(0) -{ -} - -QV8VariantWrapper::~QV8VariantWrapper() -{ -} - -void QV8VariantWrapper::init(QV8Engine *engine) -{ - m_engine = engine; - m_toString = qPersistentNew<v8::Function>(v8::FunctionTemplate::New(ToString)->GetFunction()); - m_valueOf = qPersistentNew<v8::Function>(v8::FunctionTemplate::New(ValueOf)->GetFunction()); - - { - v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New(); - ft->InstanceTemplate()->SetFallbackPropertyHandler(Getter, Setter); - ft->InstanceTemplate()->SetHasExternalResource(true); - ft->InstanceTemplate()->MarkAsUseUserObjectComparison(); - ft->InstanceTemplate()->SetAccessor(v8::String::New("toString"), ToStringGetter, 0, - m_toString, v8::DEFAULT, - v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete)); - ft->InstanceTemplate()->SetAccessor(v8::String::New("valueOf"), ValueOfGetter, 0, - m_valueOf, v8::DEFAULT, - v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete)); - m_constructor = qPersistentNew<v8::Function>(ft->GetFunction()); - } - { - m_preserve = qPersistentNew<v8::Function>(v8::FunctionTemplate::New(Preserve)->GetFunction()); - m_destroy = qPersistentNew<v8::Function>(v8::FunctionTemplate::New(Destroy)->GetFunction()); - v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New(); - ft->InstanceTemplate()->SetFallbackPropertyHandler(Getter, Setter); - ft->InstanceTemplate()->SetHasExternalResource(true); - ft->InstanceTemplate()->MarkAsUseUserObjectComparison(); - ft->InstanceTemplate()->SetAccessor(v8::String::New("preserve"), PreserveGetter, 0, - m_preserve, v8::DEFAULT, - v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete)); - ft->InstanceTemplate()->SetAccessor(v8::String::New("destroy"), DestroyGetter, 0, - m_destroy, v8::DEFAULT, - v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete)); - ft->InstanceTemplate()->SetAccessor(v8::String::New("toString"), ToStringGetter, 0, - m_toString, v8::DEFAULT, - v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete)); - ft->InstanceTemplate()->SetAccessor(v8::String::New("valueOf"), ValueOfGetter, 0, - m_valueOf, v8::DEFAULT, - v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete)); - m_scarceConstructor = qPersistentNew<v8::Function>(ft->GetFunction()); - } - -} - -void QV8VariantWrapper::destroy() -{ - qPersistentDispose(m_valueOf); - qPersistentDispose(m_toString); - qPersistentDispose(m_destroy); - qPersistentDispose(m_preserve); - qPersistentDispose(m_scarceConstructor); - qPersistentDispose(m_constructor); -} - -v8::Local<v8::Object> QV8VariantWrapper::newVariant(const QVariant &value) -{ - bool scarceResource = value.type() == QVariant::Pixmap || - value.type() == QVariant::Image; - - // XXX NewInstance() should be optimized - v8::Local<v8::Object> rv; - QV8VariantResource *r = new QV8VariantResource(m_engine, value); - - if (scarceResource) { - QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(m_engine->engine()); - Q_ASSERT(ep->scarceResourcesRefCount); - rv = m_scarceConstructor->NewInstance(); - r->m_isScarceResource = true; - ep->scarceResources.insert(r); - } else { - rv = m_constructor->NewInstance(); - } - - rv->SetExternalResource(r); - return rv; -} - -bool QV8VariantWrapper::isVariant(v8::Handle<v8::Value> value) -{ - return value->IsObject() && v8_resource_cast<QV8VariantResource>(value->ToObject()); -} - -QVariant QV8VariantWrapper::toVariant(v8::Handle<v8::Object> obj) -{ - QV8VariantResource *r = v8_resource_cast<QV8VariantResource>(obj); - return r?r->data:QVariant(); -} - -QVariant QV8VariantWrapper::toVariant(QV8ObjectResource *r) -{ - Q_ASSERT(r->resourceType() == QV8ObjectResource::VariantType); - return static_cast<QV8VariantResource *>(r)->data; -} - -QVariant &QV8VariantWrapper::variantValue(v8::Handle<v8::Value> value) -{ - Q_ASSERT(isVariant(value)); - QV8VariantResource *r = v8_resource_cast<QV8VariantResource>(value->ToObject()); - return static_cast<QV8VariantResource *>(r)->data; -} - -v8::Handle<v8::Value> QV8VariantWrapper::Getter(v8::Local<v8::String> /* property */, - const v8::AccessorInfo & /* info */) -{ - return v8::Handle<v8::Value>(); -} - -v8::Handle<v8::Value> QV8VariantWrapper::Setter(v8::Local<v8::String> /* property */, - v8::Local<v8::Value> value, - const v8::AccessorInfo & /* info */) -{ - return value; -} - -v8::Handle<v8::Value> QV8VariantWrapper::PreserveGetter(v8::Local<v8::String> property, - const v8::AccessorInfo &info) -{ - Q_UNUSED(property); - return info.Data(); -} - -v8::Handle<v8::Value> QV8VariantWrapper::DestroyGetter(v8::Local<v8::String> property, - const v8::AccessorInfo &info) -{ - Q_UNUSED(property); - return info.Data(); -} - -v8::Handle<v8::Value> QV8VariantWrapper::ToStringGetter(v8::Local<v8::String> property, - const v8::AccessorInfo &info) -{ - Q_UNUSED(property); - return info.Data(); -} - -v8::Handle<v8::Value> QV8VariantWrapper::ValueOfGetter(v8::Local<v8::String> property, - const v8::AccessorInfo &info) -{ - Q_UNUSED(property); - return info.Data(); -} - -v8::Handle<v8::Value> QV8VariantWrapper::Preserve(const v8::Arguments &args) -{ - QV8VariantResource *resource = v8_resource_cast<QV8VariantResource>(args.This()); - if (resource) { - resource->node.remove(); - } - return v8::Undefined(); -} - -v8::Handle<v8::Value> QV8VariantWrapper::Destroy(const v8::Arguments &args) -{ - QV8VariantResource *resource = v8_resource_cast<QV8VariantResource>(args.This()); - if (resource) { - resource->data = QVariant(); - resource->node.remove(); - } - return v8::Undefined(); -} - -v8::Handle<v8::Value> QV8VariantWrapper::ToString(const v8::Arguments &args) -{ - QV8VariantResource *resource = v8_resource_cast<QV8VariantResource>(args.This()); - if (resource) { - QString result = resource->data.toString(); - if (result.isEmpty() && !resource->data.canConvert(QVariant::String)) - result = QString::fromLatin1("QVariant(%0)").arg(QString::fromLatin1(resource->data.typeName())); - return resource->engine->toString(result); - } else { - return v8::Undefined(); - } -} - -v8::Handle<v8::Value> QV8VariantWrapper::ValueOf(const v8::Arguments &args) -{ - QV8VariantResource *resource = v8_resource_cast<QV8VariantResource>(args.This()); - if (resource) { - QVariant v = resource->data; - switch (v.type()) { - case QVariant::Invalid: - return v8::Undefined(); - case QVariant::String: - return resource->engine->toString(v.toString()); - case QVariant::Int: - case QVariant::Double: - case QVariant::UInt: - return v8::Number::New(v.toDouble()); - case QVariant::Bool: - return v8::Boolean::New(v.toBool()); - default: - break; - } - } - return args.This(); -} - -QT_END_NAMESPACE diff --git a/src/declarative/qml/v8/qv8variantwrapper_p.h b/src/declarative/qml/v8/qv8variantwrapper_p.h deleted file mode 100644 index 578acf01c8..0000000000 --- a/src/declarative/qml/v8/qv8variantwrapper_p.h +++ /dev/null @@ -1,110 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QV8VARIANTWRAPPER_P_H -#define QV8VARIANTWRAPPER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/qglobal.h> -#include <QtDeclarative/qdeclarativelist.h> -#include <private/qv8_p.h> - -QT_BEGIN_NAMESPACE - -class QV8Engine; -class QV8ObjectResource; -class QV8VariantWrapper -{ -public: - QV8VariantWrapper(); - ~QV8VariantWrapper(); - - void init(QV8Engine *); - void destroy(); - - v8::Local<v8::Object> newVariant(const QVariant &); - bool isVariant(v8::Handle<v8::Value>); - static QVariant toVariant(v8::Handle<v8::Object>); - static QVariant toVariant(QV8ObjectResource *); - QVariant &variantValue(v8::Handle<v8::Value>); - -private: - static v8::Handle<v8::Value> Getter(v8::Local<v8::String> property, - const v8::AccessorInfo &info); - static v8::Handle<v8::Value> Setter(v8::Local<v8::String> property, - v8::Local<v8::Value> value, - const v8::AccessorInfo &info); - static v8::Handle<v8::Value> PreserveGetter(v8::Local<v8::String> property, - const v8::AccessorInfo &info); - static v8::Handle<v8::Value> DestroyGetter(v8::Local<v8::String> property, - const v8::AccessorInfo &info); - static v8::Handle<v8::Value> ToStringGetter(v8::Local<v8::String> property, - const v8::AccessorInfo &info); - static v8::Handle<v8::Value> ValueOfGetter(v8::Local<v8::String> property, - const v8::AccessorInfo &info); - static v8::Handle<v8::Value> Preserve(const v8::Arguments &args); - static v8::Handle<v8::Value> Destroy(const v8::Arguments &args); - static v8::Handle<v8::Value> ToString(const v8::Arguments &args); - static v8::Handle<v8::Value> ValueOf(const v8::Arguments &args); - - QV8Engine *m_engine; - v8::Persistent<v8::Function> m_constructor; - v8::Persistent<v8::Function> m_scarceConstructor; - v8::Persistent<v8::Function> m_preserve; - v8::Persistent<v8::Function> m_destroy; - v8::Persistent<v8::Function> m_toString; - v8::Persistent<v8::Function> m_valueOf; -}; - -QT_END_NAMESPACE - -#endif // QV8VARIANTWRAPPER_P_H - diff --git a/src/declarative/qml/v8/qv8worker.cpp b/src/declarative/qml/v8/qv8worker.cpp deleted file mode 100644 index 90c8b8441d..0000000000 --- a/src/declarative/qml/v8/qv8worker.cpp +++ /dev/null @@ -1,392 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qv8worker_p.h" - -#include <private/qdeclarativelistmodel_p.h> -#include <private/qdeclarativelistmodelworkeragent_p.h> - -QT_BEGIN_NAMESPACE - -// We allow the following JavaScript types to be passed between the main and -// the secondary thread: -// + undefined -// + null -// + Boolean -// + String -// + Function -// + Array -// + "Simple" Objects -// + Number -// + Date -// + RegExp -// <quint8 type><quint24 size><data> - -enum Type { - WorkerUndefined, - WorkerNull, - WorkerTrue, - WorkerFalse, - WorkerString, - WorkerFunction, - WorkerArray, - WorkerObject, - WorkerInt32, - WorkerUint32, - WorkerNumber, - WorkerDate, - WorkerRegexp, - WorkerListModel, - WorkerSequence -}; - -static inline quint32 valueheader(Type type, quint32 size = 0) -{ - return quint8(type) << 24 | (size & 0xFFFFFF); -} - -static inline Type headertype(quint32 header) -{ - return (Type)(header >> 24); -} - -static inline quint32 headersize(quint32 header) -{ - return header & 0xFFFFFF; -} - -static inline void push(QByteArray &data, quint32 value) -{ - data.append((const char *)&value, sizeof(quint32)); -} - -static inline void push(QByteArray &data, double value) -{ - data.append((const char *)&value, sizeof(double)); -} - -static inline void push(QByteArray &data, void *ptr) -{ - data.append((const char *)&ptr, sizeof(void *)); -} - -static inline void reserve(QByteArray &data, int extra) -{ - data.reserve(data.size() + extra); -} - -static inline quint32 popUint32(const char *&data) -{ - quint32 rv = *((quint32 *)data); - data += sizeof(quint32); - return rv; -} - -static inline double popDouble(const char *&data) -{ - double rv = *((double *)data); - data += sizeof(double); - return rv; -} - -static inline void *popPtr(const char *&data) -{ - void *rv = *((void **)data); - data += sizeof(void *); - return rv; -} - -// XXX TODO: Check that worker script is exception safe in the case of -// serialization/deserialization failures - -#define ALIGN(size) (((size) + 3) & ~3) -void QV8Worker::serialize(QByteArray &data, v8::Handle<v8::Value> v, QV8Engine *engine) -{ - if (v.IsEmpty()) { - } else if (v->IsUndefined()) { - push(data, valueheader(WorkerUndefined)); - } else if (v->IsNull()) { - push(data, valueheader(WorkerNull)); - } else if (v->IsTrue()) { - push(data, valueheader(WorkerTrue)); - } else if (v->IsFalse()) { - push(data, valueheader(WorkerFalse)); - } else if (v->IsString()) { - v8::Handle<v8::String> string = v->ToString(); - int length = string->Length() + 1; - if (length > 0xFFFFFF) { - push(data, valueheader(WorkerUndefined)); - return; - } - int utf16size = ALIGN(length * sizeof(uint16_t)); - - reserve(data, utf16size + sizeof(quint32)); - push(data, valueheader(WorkerString, length)); - - int offset = data.size(); - data.resize(data.size() + utf16size); - char *buffer = data.data() + offset; - - string->Write((uint16_t*)buffer); - } else if (v->IsFunction()) { - // XXX TODO: Implement passing function objects between the main and - // worker scripts - push(data, valueheader(WorkerUndefined)); - } else if (v->IsArray()) { - v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(v); - uint32_t length = array->Length(); - if (length > 0xFFFFFF) { - push(data, valueheader(WorkerUndefined)); - return; - } - reserve(data, sizeof(quint32) + length * sizeof(quint32)); - push(data, valueheader(WorkerArray, length)); - for (uint32_t ii = 0; ii < length; ++ii) - serialize(data, array->Get(ii), engine); - } else if (v->IsInt32()) { - reserve(data, 2 * sizeof(quint32)); - push(data, valueheader(WorkerInt32)); - push(data, (quint32)v->Int32Value()); - } else if (v->IsUint32()) { - reserve(data, 2 * sizeof(quint32)); - push(data, valueheader(WorkerUint32)); - push(data, v->Uint32Value()); - } else if (v->IsNumber()) { - reserve(data, sizeof(quint32) + sizeof(double)); - push(data, valueheader(WorkerNumber)); - push(data, v->NumberValue()); - } else if (v->IsDate()) { - reserve(data, sizeof(quint32) + sizeof(double)); - push(data, valueheader(WorkerDate)); - push(data, v8::Handle<v8::Date>::Cast(v)->NumberValue()); - } else if (v->IsRegExp()) { - v8::Handle<v8::RegExp> regexp = v8::Handle<v8::RegExp>::Cast(v); - quint32 flags = regexp->GetFlags(); - v8::Local<v8::String> source = regexp->GetSource(); - - int length = source->Length() + 1; - if (length > 0xFFFFFF) { - push(data, valueheader(WorkerUndefined)); - return; - } - int utf16size = ALIGN(length * sizeof(uint16_t)); - - reserve(data, sizeof(quint32) + utf16size); - push(data, valueheader(WorkerRegexp, flags)); - push(data, (quint32)length); - int offset = data.size(); - data.resize(data.size() + utf16size); - char *buffer = data.data() + offset; - - source->Write((uint16_t*)buffer); - } else if (v->IsObject() && !v->ToObject()->GetExternalResource()) { - v8::Handle<v8::Object> object = v->ToObject(); - v8::Local<v8::Array> properties = engine->getOwnPropertyNames(object); - quint32 length = properties->Length(); - if (length > 0xFFFFFF) { - push(data, valueheader(WorkerUndefined)); - return; - } - push(data, valueheader(WorkerObject, length)); - v8::TryCatch tc; - for (quint32 ii = 0; ii < length; ++ii) { - v8::Local<v8::String> str = properties->Get(ii)->ToString(); - serialize(data, str, engine); - - v8::Local<v8::Value> val = object->Get(str); - if (tc.HasCaught()) { - serialize(data, v8::Undefined(), engine); - tc.Reset(); - } else { - serialize(data, val, engine); - } - } - } else if (engine->isQObject(v)) { - // XXX TODO: Generalize passing objects between the main thread and worker scripts so - // that others can trivially plug in their elements. - QDeclarativeListModel *lm = qobject_cast<QDeclarativeListModel *>(engine->toQObject(v)); - if (lm && lm->agent()) { - QDeclarativeListModelWorkerAgent *agent = lm->agent(); - agent->addref(); - push(data, valueheader(WorkerListModel)); - push(data, (void *)agent); - return; - } - // No other QObject's are allowed to be sent - push(data, valueheader(WorkerUndefined)); - } else { - // we can convert sequences, but not other types with external data. - if (v->IsObject()) { - v8::Handle<v8::Object> seqObj = v->ToObject(); - QV8ObjectResource *r = static_cast<QV8ObjectResource *>(seqObj->GetExternalResource()); - if (r->resourceType() == QV8ObjectResource::SequenceType) { - QVariant sequenceVariant = engine->sequenceWrapper()->toVariant(r); - if (!sequenceVariant.isNull()) { - // valid sequence. we generate a length (sequence length + 1 for the sequence type) - uint32_t seqLength = engine->sequenceWrapper()->sequenceLength(r); - uint32_t length = seqLength + 1; - if (length > 0xFFFFFF) { - push(data, valueheader(WorkerUndefined)); - return; - } - reserve(data, sizeof(quint32) + length * sizeof(quint32)); - push(data, valueheader(WorkerSequence, length)); - serialize(data, v8::Integer::New(sequenceVariant.userType()), engine); // sequence type - for (uint32_t ii = 0; ii < seqLength; ++ii) { - serialize(data, seqObj->Get(ii), engine); // sequence elements - } - - return; - } - } - } - - // not a sequence. - push(data, valueheader(WorkerUndefined)); - } -} - -v8::Handle<v8::Value> QV8Worker::deserialize(const char *&data, QV8Engine *engine) -{ - quint32 header = popUint32(data); - Type type = headertype(header); - - switch (type) { - case WorkerUndefined: - return v8::Undefined(); - case WorkerNull: - return v8::Null(); - case WorkerTrue: - return v8::True(); - case WorkerFalse: - return v8::False(); - case WorkerString: - { - quint32 size = headersize(header); - v8::Local<v8::String> string = v8::String::New((uint16_t*)data, size - 1); - data += ALIGN(size * sizeof(uint16_t)); - return string; - } - case WorkerFunction: - Q_ASSERT(!"Unreachable"); - break; - case WorkerArray: - { - quint32 size = headersize(header); - v8::Local<v8::Array> array = v8::Array::New(size); - for (quint32 ii = 0; ii < size; ++ii) { - array->Set(ii, deserialize(data, engine)); - } - return array; - } - case WorkerObject: - { - quint32 size = headersize(header); - v8::Local<v8::Object> o = v8::Object::New(); - for (quint32 ii = 0; ii < size; ++ii) { - v8::Handle<v8::Value> name = deserialize(data, engine); - v8::Handle<v8::Value> value = deserialize(data, engine); - o->Set(name, value); - } - return o; - } - case WorkerInt32: - return v8::Integer::New((qint32)popUint32(data)); - case WorkerUint32: - return v8::Integer::NewFromUnsigned(popUint32(data)); - case WorkerNumber: - return v8::Number::New(popDouble(data)); - case WorkerDate: - return v8::Date::New(popDouble(data)); - case WorkerRegexp: - { - quint32 flags = headersize(header); - quint32 length = popUint32(data); - v8::Local<v8::String> source = v8::String::New((uint16_t*)data, length - 1); - data += ALIGN(length * sizeof(uint16_t)); - return v8::RegExp::New(source, (v8::RegExp::Flags)flags); - } - case WorkerListModel: - { - void *ptr = popPtr(data); - QDeclarativeListModelWorkerAgent *agent = (QDeclarativeListModelWorkerAgent *)ptr; - v8::Handle<v8::Value> rv = engine->newQObject(agent); - if (rv->IsObject()) { - QDeclarativeListModelWorkerAgent::VariantRef ref(agent); - QVariant var = qVariantFromValue(ref); - rv->ToObject()->SetHiddenValue(v8::String::New("qml::ref"), engine->fromVariant(var)); - } - agent->release(); - agent->setV8Engine(engine); - return rv; - } - case WorkerSequence: - { - bool succeeded = false; - quint32 length = headersize(header); - quint32 seqLength = length - 1; - int sequenceType = deserialize(data, engine)->Int32Value(); - v8::Local<v8::Array> array = v8::Array::New(seqLength); - for (quint32 ii = 0; ii < seqLength; ++ii) - array->Set(ii, deserialize(data, engine)); - QVariant seqVariant = engine->sequenceWrapper()->toVariant(array, sequenceType, &succeeded); - return engine->sequenceWrapper()->fromVariant(seqVariant, &succeeded); - } - } - Q_ASSERT(!"Unreachable"); - return v8::Undefined(); -} - -QByteArray QV8Worker::serialize(v8::Handle<v8::Value> value, QV8Engine *engine) -{ - QByteArray rv; - serialize(rv, value, engine); - return rv; -} - -v8::Handle<v8::Value> QV8Worker::deserialize(const QByteArray &data, QV8Engine *engine) -{ - const char *stream = data.constData(); - return deserialize(stream, engine); -} - -QT_END_NAMESPACE - diff --git a/src/declarative/qml/v8/qv8worker_p.h b/src/declarative/qml/v8/qv8worker_p.h deleted file mode 100644 index f920446b27..0000000000 --- a/src/declarative/qml/v8/qv8worker_p.h +++ /dev/null @@ -1,75 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the QtDeclarative module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** 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, Nokia gives you certain additional -** rights. These rights are described in the Nokia 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. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QV8WORKER_P_H -#define QV8WORKER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qv8engine_p.h" - -QT_BEGIN_NAMESPACE - -class QV8Worker { -public: - struct SavedData { - }; - - static QByteArray serialize(v8::Handle<v8::Value>, QV8Engine *); - static v8::Handle<v8::Value> deserialize(const QByteArray &, QV8Engine *); - -private: - static void serialize(QByteArray &, v8::Handle<v8::Value>, QV8Engine *); - static v8::Handle<v8::Value> deserialize(const char *&, QV8Engine *); -}; - -QT_END_NAMESPACE - -#endif // QV8WORKER_P_H diff --git a/src/declarative/qml/v8/script.pri b/src/declarative/qml/v8/script.pri deleted file mode 100644 index 3439413f5e..0000000000 --- a/src/declarative/qml/v8/script.pri +++ /dev/null @@ -1,21 +0,0 @@ -SOURCES += \ - $$PWD/qjsengine.cpp \ - $$PWD/qjsvalue.cpp \ - $$PWD/qjsvalueiterator.cpp \ - -HEADERS += \ - $$PWD/qjsengine.h \ - $$PWD/qjsengine_p.h \ - $$PWD/qjsvalue.h \ - $$PWD/qjsvalue_p.h \ - $$PWD/qjsvalueiterator.h \ - $$PWD/qjsvalue_impl_p.h \ - $$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/declarative/qml/v8/v8.pri b/src/declarative/qml/v8/v8.pri deleted file mode 100644 index 72416c4dbb..0000000000 --- a/src/declarative/qml/v8/v8.pri +++ /dev/null @@ -1,45 +0,0 @@ -INCLUDEPATH += $$PWD/../../../3rdparty/javascriptcore - -include(script.pri) - -HEADERS += \ - $$PWD/qv8_p.h \ - $$PWD/qv8debug_p.h \ - $$PWD/qv8profiler_p.h \ - $$PWD/qv8stringwrapper_p.h \ - $$PWD/qv8engine_p.h \ - $$PWD/qv8sequencewrapper_p.h \ - $$PWD/qv8sequencewrapper_p_p.h \ - $$PWD/qv8contextwrapper_p.h \ - $$PWD/qv8qobjectwrapper_p.h \ - $$PWD/qv8typewrapper_p.h \ - $$PWD/qv8listwrapper_p.h \ - $$PWD/qv8variantwrapper_p.h \ - $$PWD/qv8variantresource_p.h \ - $$PWD/qv8valuetypewrapper_p.h \ - $$PWD/qv8include_p.h \ - $$PWD/qv8worker_p.h \ - $$PWD/qv8bindings_p.h \ - $$PWD/../../../3rdparty/javascriptcore/DateMath.h \ - $$PWD/qv8engine_impl_p.h \ - $$PWD/qv8domerrors_p.h \ - $$PWD/qv8sqlerrors_p.h \ - $$PWD/qdeclarativebuiltinfunctions_p.h - -SOURCES += \ - $$PWD/qv8stringwrapper.cpp \ - $$PWD/qv8engine.cpp \ - $$PWD/qv8sequencewrapper.cpp \ - $$PWD/qv8contextwrapper.cpp \ - $$PWD/qv8qobjectwrapper.cpp \ - $$PWD/qv8typewrapper.cpp \ - $$PWD/qv8listwrapper.cpp \ - $$PWD/qv8variantwrapper.cpp \ - $$PWD/qv8valuetypewrapper.cpp \ - $$PWD/qv8include.cpp \ - $$PWD/qv8worker.cpp \ - $$PWD/qv8bindings.cpp \ - $$PWD/../../../3rdparty/javascriptcore/DateMath.cpp \ - $$PWD/qv8domerrors.cpp \ - $$PWD/qv8sqlerrors.cpp \ - $$PWD/qdeclarativebuiltinfunctions.cpp
\ No newline at end of file |