| /**************************************************************************** |
| ** |
| ** Copyright (C) 2015 The Qt Company Ltd. |
| ** Contact: http://www.qt.io/licensing/ |
| ** |
| ** This file is part of the QtScript module of the Qt Toolkit. |
| ** |
| ** $QT_BEGIN_LICENSE:LGPL$ |
| ** Commercial License Usage |
| ** Licensees holding valid commercial Qt licenses may use this file in |
| ** accordance with the commercial license agreement provided with the |
| ** Software or, alternatively, in accordance with the terms contained in |
| ** a written agreement between you and The Qt Company. For licensing terms |
| ** and conditions see https://www.qt.io/terms-conditions. For further |
| ** information use the contact form at https://www.qt.io/contact-us. |
| ** |
| ** GNU Lesser General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU Lesser |
| ** General Public License version 3 as published by the Free Software |
| ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
| ** packaging of this file. Please review the following information to |
| ** ensure the GNU Lesser General Public License version 3 requirements |
| ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
| ** |
| ** GNU General Public License Usage |
| ** Alternatively, this file may be used under the terms of the GNU |
| ** General Public License version 2.0 or (at your option) the GNU General |
| ** Public license version 3 or any later version approved by the KDE Free |
| ** Qt Foundation. The licenses are as published by the Free Software |
| ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
| ** included in the packaging of this file. Please review the following |
| ** information to ensure the GNU General Public License requirements will |
| ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
| ** https://www.gnu.org/licenses/gpl-3.0.html. |
| ** |
| ** $QT_END_LICENSE$ |
| ** |
| ****************************************************************************/ |
| |
| #include "config.h" |
| #include "qscriptdeclarativeobject_p.h" |
| |
| #include "../api/qscriptengine.h" |
| #include "../api/qscriptengine_p.h" |
| #include "../api/qscriptcontext.h" |
| #include "../api/qscriptcontext_p.h" |
| #include "../api/qscriptclass.h" |
| #include "../api/qscriptclasspropertyiterator.h" |
| |
| #include "Error.h" |
| #include "PropertyNameArray.h" |
| |
| #include <QtCore/qstringlist.h> |
| |
| Q_DECLARE_METATYPE(QScriptContext*) |
| Q_DECLARE_METATYPE(QScriptValue) |
| Q_DECLARE_METATYPE(QScriptValueList) |
| |
| QT_BEGIN_NAMESPACE |
| |
| namespace QScript |
| { |
| |
| DeclarativeObjectDelegate::DeclarativeObjectDelegate(QScriptDeclarativeClass *c, |
| QScriptDeclarativeClass::Object *o) |
| : m_class(c), m_object(o) |
| { |
| } |
| |
| DeclarativeObjectDelegate::~DeclarativeObjectDelegate() |
| { |
| delete m_object; |
| } |
| |
| QScriptObjectDelegate::Type DeclarativeObjectDelegate::type() const |
| { |
| return DeclarativeClassObject; |
| } |
| |
| bool DeclarativeObjectDelegate::getOwnPropertySlot(QScriptObject* object, |
| JSC::ExecState *exec, |
| const JSC::Identifier &propertyName, |
| JSC::PropertySlot &slot) |
| { |
| QScriptDeclarativeClass::Identifier identifier = (void *)propertyName.ustring().rep(); |
| |
| QScriptDeclarativeClassPrivate *p = QScriptDeclarativeClassPrivate::get(m_class); |
| p->context = reinterpret_cast<QScriptContext *>(exec); |
| QScriptClass::QueryFlags flags = |
| m_class->queryProperty(m_object, identifier, QScriptClass::HandlesReadAccess); |
| if (flags & QScriptClass::HandlesReadAccess) { |
| QScriptDeclarativeClass::Value val = m_class->property(m_object, identifier); |
| p->context = 0; |
| slot.setValue((const JSC::JSValue &)val); |
| return true; |
| } |
| p->context = 0; |
| |
| return QScriptObjectDelegate::getOwnPropertySlot(object, exec, propertyName, slot); |
| } |
| |
| void DeclarativeObjectDelegate::put(QScriptObject* object, JSC::ExecState *exec, |
| const JSC::Identifier &propertyName, |
| JSC::JSValue value, JSC::PutPropertySlot &slot) |
| { |
| QScriptEnginePrivate *engine = scriptEngineFromExec(exec); |
| QScript::SaveFrameHelper saveFrame(engine, exec); |
| QScriptDeclarativeClass::Identifier identifier = (void *)propertyName.ustring().rep(); |
| |
| QScriptDeclarativeClassPrivate *p = QScriptDeclarativeClassPrivate::get(m_class); |
| p->context = reinterpret_cast<QScriptContext *>(exec); |
| QScriptClass::QueryFlags flags = |
| m_class->queryProperty(m_object, identifier, QScriptClass::HandlesWriteAccess); |
| if (flags & QScriptClass::HandlesWriteAccess) { |
| m_class->setProperty(m_object, identifier, engine->scriptValueFromJSCValue(value)); |
| p->context = 0; |
| return; |
| } |
| p->context = 0; |
| |
| QScriptObjectDelegate::put(object, exec, propertyName, value, slot); |
| } |
| |
| bool DeclarativeObjectDelegate::deleteProperty(QScriptObject* object, JSC::ExecState *exec, |
| const JSC::Identifier &propertyName) |
| { |
| return QScriptObjectDelegate::deleteProperty(object, exec, propertyName); |
| } |
| |
| void DeclarativeObjectDelegate::getOwnPropertyNames(QScriptObject* object, JSC::ExecState *exec, |
| JSC::PropertyNameArray &propertyNames, |
| JSC::EnumerationMode mode) |
| { |
| QStringList properties = m_class->propertyNames(m_object); |
| for (int ii = 0; ii < properties.count(); ++ii) { |
| const QString &name = properties.at(ii); |
| propertyNames.add(JSC::Identifier(exec, name)); |
| } |
| |
| QScriptObjectDelegate::getOwnPropertyNames(object, exec, propertyNames, mode); |
| } |
| |
| JSC::CallType DeclarativeObjectDelegate::getCallData(QScriptObject *object, JSC::CallData &callData) |
| { |
| if (!QScriptDeclarativeClassPrivate::get(m_class)->supportsCall) |
| return JSC::CallTypeNone; |
| callData.native.function = call; |
| return JSC::CallTypeHost; |
| } |
| |
| JSC::JSValue DeclarativeObjectDelegate::call(JSC::ExecState *exec, JSC::JSObject *callee, |
| JSC::JSValue thisValue, const JSC::ArgList &args) |
| { |
| if (!callee->inherits(&QScriptObject::info)) |
| return JSC::throwError(exec, JSC::TypeError, "callee is not a DeclarativeObject object"); |
| QScriptObject *obj = static_cast<QScriptObject*>(callee); |
| QScriptObjectDelegate *delegate = obj->delegate(); |
| if (!delegate || (delegate->type() != QScriptObjectDelegate::DeclarativeClassObject)) |
| return JSC::throwError(exec, JSC::TypeError, "callee is not a DeclarativeObject object"); |
| |
| QScriptDeclarativeClass *scriptClass = static_cast<DeclarativeObjectDelegate*>(delegate)->m_class; |
| QScriptEnginePrivate *eng_p = scriptEngineFromExec(exec); |
| |
| QScript::SaveFrameHelper saveFrame(eng_p, exec); |
| eng_p->pushContext(exec, thisValue, args, callee); |
| QScriptContext *ctxt = eng_p->contextForFrame(eng_p->currentFrame); |
| |
| QScriptValue scriptObject = eng_p->scriptValueFromJSCValue(obj); |
| QScriptDeclarativeClass::Value result = |
| scriptClass->call(static_cast<DeclarativeObjectDelegate*>(delegate)->m_object, ctxt); |
| |
| eng_p->popContext(); |
| return (JSC::JSValue &)(result); |
| } |
| |
| JSC::ConstructType DeclarativeObjectDelegate::getConstructData(QScriptObject* object, JSC::ConstructData &constructData) |
| { |
| return QScriptObjectDelegate::getConstructData(object, constructData); |
| } |
| |
| bool DeclarativeObjectDelegate::hasInstance(QScriptObject* object, JSC::ExecState *exec, |
| JSC::JSValue value, JSC::JSValue proto) |
| { |
| return QScriptObjectDelegate::hasInstance(object, exec, value, proto); |
| } |
| |
| bool DeclarativeObjectDelegate::compareToObject(QScriptObject *o, JSC::ExecState *exec, JSC::JSObject *o2) |
| { |
| if (!o2->inherits(&QScriptObject::info)) |
| return false; |
| |
| QScriptObject *scriptObject = static_cast<QScriptObject*>(o2); |
| QScriptObjectDelegate *delegate = scriptObject->delegate(); |
| if (!delegate || (delegate->type() != QScriptObjectDelegate::DeclarativeClassObject)) |
| return false; |
| |
| DeclarativeObjectDelegate *other = static_cast<DeclarativeObjectDelegate*>(delegate); |
| if (m_class != other->m_class) |
| return false; |
| else |
| return m_class->compare(m_object, other->m_object); |
| } |
| |
| } // namespace QScript |
| |
| QT_END_NAMESPACE |