1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qv8variantwrapper_p.h"
43 #include "qv8variantresource_p.h"
44 #include "qv8engine_p.h"
45 #include <private/qdeclarativeengine_p.h>
49 QV8VariantResource::QV8VariantResource(QV8Engine *engine, const QVariant &data)
50 : QV8ObjectResource(engine), QDeclarativeEnginePrivate::ScarceResourceData(data), m_isScarceResource(false), m_vmePropertyReferenceCount(0)
54 void QV8VariantResource::addVmePropertyReference()
56 if (m_isScarceResource && ++m_vmePropertyReferenceCount == 1) {
57 // remove from the ep->scarceResources list
58 // since it is now no longer eligible to be
59 // released automatically by the engine.
64 void QV8VariantResource::removeVmePropertyReference()
66 if (m_isScarceResource && --m_vmePropertyReferenceCount == 0) {
67 // and add to the ep->scarceResources list
68 // since it is now eligible to be released
69 // automatically by the engine.
70 QDeclarativeEnginePrivate::get(engine->engine())->scarceResources.insert(this);
74 QV8VariantWrapper::QV8VariantWrapper()
79 QV8VariantWrapper::~QV8VariantWrapper()
83 void QV8VariantWrapper::init(QV8Engine *engine)
86 m_toString = qPersistentNew<v8::Function>(v8::FunctionTemplate::New(ToString)->GetFunction());
87 m_valueOf = qPersistentNew<v8::Function>(v8::FunctionTemplate::New(ValueOf)->GetFunction());
90 v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
91 ft->InstanceTemplate()->SetFallbackPropertyHandler(Getter, Setter);
92 ft->InstanceTemplate()->SetHasExternalResource(true);
93 ft->InstanceTemplate()->MarkAsUseUserObjectComparison();
94 ft->InstanceTemplate()->SetAccessor(v8::String::New("toString"), ToStringGetter, 0,
95 m_toString, v8::DEFAULT,
96 v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete));
97 ft->InstanceTemplate()->SetAccessor(v8::String::New("valueOf"), ValueOfGetter, 0,
98 m_valueOf, v8::DEFAULT,
99 v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete));
100 m_constructor = qPersistentNew<v8::Function>(ft->GetFunction());
103 m_preserve = qPersistentNew<v8::Function>(v8::FunctionTemplate::New(Preserve)->GetFunction());
104 m_destroy = qPersistentNew<v8::Function>(v8::FunctionTemplate::New(Destroy)->GetFunction());
105 v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New();
106 ft->InstanceTemplate()->SetFallbackPropertyHandler(Getter, Setter);
107 ft->InstanceTemplate()->SetHasExternalResource(true);
108 ft->InstanceTemplate()->MarkAsUseUserObjectComparison();
109 ft->InstanceTemplate()->SetAccessor(v8::String::New("preserve"), PreserveGetter, 0,
110 m_preserve, v8::DEFAULT,
111 v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete));
112 ft->InstanceTemplate()->SetAccessor(v8::String::New("destroy"), DestroyGetter, 0,
113 m_destroy, v8::DEFAULT,
114 v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete));
115 ft->InstanceTemplate()->SetAccessor(v8::String::New("toString"), ToStringGetter, 0,
116 m_toString, v8::DEFAULT,
117 v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete));
118 ft->InstanceTemplate()->SetAccessor(v8::String::New("valueOf"), ValueOfGetter, 0,
119 m_valueOf, v8::DEFAULT,
120 v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete));
121 m_scarceConstructor = qPersistentNew<v8::Function>(ft->GetFunction());
126 void QV8VariantWrapper::destroy()
128 qPersistentDispose(m_valueOf);
129 qPersistentDispose(m_toString);
130 qPersistentDispose(m_destroy);
131 qPersistentDispose(m_preserve);
132 qPersistentDispose(m_scarceConstructor);
133 qPersistentDispose(m_constructor);
136 v8::Local<v8::Object> QV8VariantWrapper::newVariant(const QVariant &value)
138 bool scarceResource = value.type() == QVariant::Pixmap ||
139 value.type() == QVariant::Image;
141 // XXX NewInstance() should be optimized
142 v8::Local<v8::Object> rv;
143 QV8VariantResource *r = new QV8VariantResource(m_engine, value);
145 if (scarceResource) {
146 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(m_engine->engine());
147 Q_ASSERT(ep->scarceResourcesRefCount);
148 rv = m_scarceConstructor->NewInstance();
149 r->m_isScarceResource = true;
150 ep->scarceResources.insert(r);
152 rv = m_constructor->NewInstance();
155 rv->SetExternalResource(r);
159 bool QV8VariantWrapper::isVariant(v8::Handle<v8::Value> value)
161 return value->IsObject() && v8_resource_cast<QV8VariantResource>(value->ToObject());
164 QVariant QV8VariantWrapper::toVariant(v8::Handle<v8::Object> obj)
166 QV8VariantResource *r = v8_resource_cast<QV8VariantResource>(obj);
167 return r?r->data:QVariant();
170 QVariant QV8VariantWrapper::toVariant(QV8ObjectResource *r)
172 Q_ASSERT(r->resourceType() == QV8ObjectResource::VariantType);
173 return static_cast<QV8VariantResource *>(r)->data;
176 QVariant &QV8VariantWrapper::variantValue(v8::Handle<v8::Value> value)
178 Q_ASSERT(isVariant(value));
179 QV8VariantResource *r = v8_resource_cast<QV8VariantResource>(value->ToObject());
180 return static_cast<QV8VariantResource *>(r)->data;
183 v8::Handle<v8::Value> QV8VariantWrapper::Getter(v8::Local<v8::String> /* property */,
184 const v8::AccessorInfo & /* info */)
186 return v8::Handle<v8::Value>();
189 v8::Handle<v8::Value> QV8VariantWrapper::Setter(v8::Local<v8::String> /* property */,
190 v8::Local<v8::Value> value,
191 const v8::AccessorInfo & /* info */)
196 v8::Handle<v8::Value> QV8VariantWrapper::PreserveGetter(v8::Local<v8::String> property,
197 const v8::AccessorInfo &info)
203 v8::Handle<v8::Value> QV8VariantWrapper::DestroyGetter(v8::Local<v8::String> property,
204 const v8::AccessorInfo &info)
210 v8::Handle<v8::Value> QV8VariantWrapper::ToStringGetter(v8::Local<v8::String> property,
211 const v8::AccessorInfo &info)
217 v8::Handle<v8::Value> QV8VariantWrapper::ValueOfGetter(v8::Local<v8::String> property,
218 const v8::AccessorInfo &info)
224 v8::Handle<v8::Value> QV8VariantWrapper::Preserve(const v8::Arguments &args)
226 QV8VariantResource *resource = v8_resource_cast<QV8VariantResource>(args.This());
228 resource->node.remove();
230 return v8::Undefined();
233 v8::Handle<v8::Value> QV8VariantWrapper::Destroy(const v8::Arguments &args)
235 QV8VariantResource *resource = v8_resource_cast<QV8VariantResource>(args.This());
237 resource->data = QVariant();
238 resource->node.remove();
240 return v8::Undefined();
243 v8::Handle<v8::Value> QV8VariantWrapper::ToString(const v8::Arguments &args)
245 QV8VariantResource *resource = v8_resource_cast<QV8VariantResource>(args.This());
247 QString result = resource->data.toString();
248 if (result.isEmpty() && !resource->data.canConvert(QVariant::String))
249 result = QString::fromLatin1("QVariant(%0)").arg(QString::fromLatin1(resource->data.typeName()));
250 return resource->engine->toString(result);
252 return v8::Undefined();
256 v8::Handle<v8::Value> QV8VariantWrapper::ValueOf(const v8::Arguments &args)
258 QV8VariantResource *resource = v8_resource_cast<QV8VariantResource>(args.This());
260 QVariant v = resource->data;
262 case QVariant::Invalid:
263 return v8::Undefined();
264 case QVariant::String:
265 return resource->engine->toString(v.toString());
267 case QVariant::Double:
269 return v8::Number::New(v.toDouble());
271 return v8::Boolean::New(v.toBool());