2 Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
20 #ifndef qscriptengine_p_h
21 #define qscriptengine_p_h
23 #include "qscriptconverter_p.h"
24 #include "qscriptengine.h"
25 #include "qscriptoriginalglobalobject_p.h"
26 #include "qscriptstring_p.h"
27 #include "qscriptsyntaxcheckresult_p.h"
28 #include "qscriptvalue.h"
29 #include <JavaScriptCore/JavaScript.h>
30 #include <JavaScriptCore/JSRetainPtr.h>
31 #include <JSBasePrivate.h>
32 #include <QtCore/qshareddata.h>
33 #include <QtCore/qstring.h>
34 #include <QtCore/qstringlist.h>
37 class QScriptSyntaxCheckResultPrivate
;
39 class QScriptEnginePrivate
: public QSharedData
{
41 static QScriptEnginePrivate
* get(const QScriptEngine
* q
) { Q_ASSERT(q
); return q
->d_ptr
.data(); }
42 static QScriptEngine
* get(const QScriptEnginePrivate
* d
) { Q_ASSERT(d
); return d
->q_ptr
; }
44 QScriptEnginePrivate(const QScriptEngine
*);
45 ~QScriptEnginePrivate();
47 enum SetExceptionFlag
{
48 IgnoreNullException
= 0x01,
49 NotNullException
= 0x02,
52 QScriptSyntaxCheckResultPrivate
* checkSyntax(const QString
& program
);
53 QScriptValuePrivate
* evaluate(const QString
& program
, const QString
& fileName
, int lineNumber
);
54 QScriptValuePrivate
* evaluate(const QScriptProgramPrivate
* program
);
55 inline JSValueRef
evaluate(JSStringRef program
, JSStringRef fileName
, int lineNumber
);
57 inline bool hasUncaughtException() const;
58 QScriptValuePrivate
* uncaughtException() const;
59 inline void clearExceptions();
60 inline void setException(JSValueRef exception
, const /* SetExceptionFlags */ unsigned flags
= IgnoreNullException
);
61 inline int uncaughtExceptionLineNumber() const;
62 inline QStringList
uncaughtExceptionBacktrace() const;
64 inline void collectGarbage();
65 inline void reportAdditionalMemoryCost(int cost
);
67 inline JSValueRef
makeJSValue(double number
) const;
68 inline JSValueRef
makeJSValue(int number
) const;
69 inline JSValueRef
makeJSValue(uint number
) const;
70 inline JSValueRef
makeJSValue(const QString
& string
) const;
71 inline JSValueRef
makeJSValue(bool number
) const;
72 inline JSValueRef
makeJSValue(QScriptValue::SpecialValue value
) const;
74 QScriptValuePrivate
* newFunction(QScriptEngine::FunctionSignature fun
, QScriptValuePrivate
* prototype
, int length
);
75 QScriptValuePrivate
* newFunction(QScriptEngine::FunctionWithArgSignature fun
, void* arg
);
76 QScriptValuePrivate
* newFunction(JSObjectRef funObject
, QScriptValuePrivate
* prototype
);
78 QScriptValuePrivate
* newObject() const;
79 QScriptValuePrivate
* newArray(uint length
);
80 QScriptValuePrivate
* newDate(qsreal value
);
81 QScriptValuePrivate
* globalObject() const;
83 inline QScriptStringPrivate
* toStringHandle(const QString
& str
) const;
85 inline operator JSGlobalContextRef() const;
87 inline bool isDate(JSValueRef value
) const;
88 inline bool isArray(JSValueRef value
) const;
89 inline bool isError(JSValueRef value
) const;
90 inline bool objectHasOwnProperty(JSObjectRef object
, JSStringRef property
) const;
91 inline QVector
<JSStringRef
> objectGetOwnPropertyNames(JSObjectRef object
) const;
95 JSGlobalContextRef m_context
;
96 JSValueRef m_exception
;
98 QScriptOriginalGlobalObject m_originalGlobalObject
;
100 JSClassRef m_nativeFunctionClass
;
101 JSClassRef m_nativeFunctionWithArgClass
;
106 Evaluates given JavaScript program and returns result of the evaluation.
107 \attention this function doesn't take ownership of the parameters.
110 JSValueRef
QScriptEnginePrivate::evaluate(JSStringRef program
, JSStringRef fileName
, int lineNumber
)
112 JSValueRef exception
;
113 JSValueRef result
= JSEvaluateScript(m_context
, program
, /* Global Object */ 0, fileName
, lineNumber
, &exception
);
115 setException(exception
, NotNullException
);
116 return exception
; // returns an exception
122 bool QScriptEnginePrivate::hasUncaughtException() const
127 void QScriptEnginePrivate::clearExceptions()
130 JSValueUnprotect(m_context
, m_exception
);
134 void QScriptEnginePrivate::setException(JSValueRef exception
, const /* SetExceptionFlags */ unsigned flags
)
136 if (!((flags
& NotNullException
) || exception
))
141 JSValueUnprotect(m_context
, m_exception
);
142 JSValueProtect(m_context
, exception
);
143 m_exception
= exception
;
146 int QScriptEnginePrivate::uncaughtExceptionLineNumber() const
148 if (!hasUncaughtException() || !JSValueIsObject(m_context
, m_exception
))
151 JSValueRef exception
= 0;
152 JSRetainPtr
<JSStringRef
> lineNumberPropertyName(Adopt
, QScriptConverter::toString("line"));
153 JSValueRef lineNumber
= JSObjectGetProperty(m_context
, const_cast<JSObjectRef
>(m_exception
), lineNumberPropertyName
.get(), &exception
);
154 int result
= JSValueToNumber(m_context
, lineNumber
, &exception
);
155 return exception
? -1 : result
;
158 QStringList
QScriptEnginePrivate::uncaughtExceptionBacktrace() const
160 if (!hasUncaughtException() || !JSValueIsObject(m_context
, m_exception
))
161 return QStringList();
163 JSValueRef exception
= 0;
164 JSRetainPtr
<JSStringRef
> fileNamePropertyName(Adopt
, QScriptConverter::toString("sourceURL"));
165 JSRetainPtr
<JSStringRef
> lineNumberPropertyName(Adopt
, QScriptConverter::toString("line"));
166 JSValueRef jsFileName
= JSObjectGetProperty(m_context
, const_cast<JSObjectRef
>(m_exception
), fileNamePropertyName
.get(), &exception
);
167 JSValueRef jsLineNumber
= JSObjectGetProperty(m_context
, const_cast<JSObjectRef
>(m_exception
), lineNumberPropertyName
.get(), &exception
);
168 JSRetainPtr
<JSStringRef
> fileName(Adopt
, JSValueToStringCopy(m_context
, jsFileName
, &exception
));
169 int lineNumber
= JSValueToNumber(m_context
, jsLineNumber
, &exception
);
170 return QStringList(QString::fromLatin1("<anonymous>()@%0:%1")
171 .arg(QScriptConverter::toString(fileName
.get()))
172 .arg(QScriptConverter::toString(exception
? -1 : lineNumber
)));
175 void QScriptEnginePrivate::collectGarbage()
177 JSGarbageCollect(m_context
);
180 void QScriptEnginePrivate::reportAdditionalMemoryCost(int cost
)
183 JSReportExtraMemoryCost(m_context
, cost
);
186 JSValueRef
QScriptEnginePrivate::makeJSValue(double number
) const
188 return JSValueMakeNumber(m_context
, number
);
191 JSValueRef
QScriptEnginePrivate::makeJSValue(int number
) const
193 return JSValueMakeNumber(m_context
, number
);
196 JSValueRef
QScriptEnginePrivate::makeJSValue(uint number
) const
198 return JSValueMakeNumber(m_context
, number
);
201 JSValueRef
QScriptEnginePrivate::makeJSValue(const QString
& string
) const
203 JSStringRef tmp
= QScriptConverter::toString(string
);
204 JSValueRef result
= JSValueMakeString(m_context
, tmp
);
205 JSStringRelease(tmp
);
209 JSValueRef
QScriptEnginePrivate::makeJSValue(bool value
) const
211 return JSValueMakeBoolean(m_context
, value
);
214 JSValueRef
QScriptEnginePrivate::makeJSValue(QScriptValue::SpecialValue value
) const
216 if (value
== QScriptValue::NullValue
)
217 return JSValueMakeNull(m_context
);
218 return JSValueMakeUndefined(m_context
);
221 QScriptStringPrivate
* QScriptEnginePrivate::toStringHandle(const QString
& str
) const
223 return new QScriptStringPrivate(str
);
226 QScriptEnginePrivate::operator JSGlobalContextRef() const
232 bool QScriptEnginePrivate::isDate(JSValueRef value
) const
234 return m_originalGlobalObject
.isDate(value
);
237 bool QScriptEnginePrivate::isArray(JSValueRef value
) const
239 return m_originalGlobalObject
.isArray(value
);
242 bool QScriptEnginePrivate::isError(JSValueRef value
) const
244 return m_originalGlobalObject
.isError(value
);
247 inline bool QScriptEnginePrivate::objectHasOwnProperty(JSObjectRef object
, JSStringRef property
) const
249 // FIXME We need a JSC C API function for this.
250 return m_originalGlobalObject
.objectHasOwnProperty(object
, property
);
253 inline QVector
<JSStringRef
> QScriptEnginePrivate::objectGetOwnPropertyNames(JSObjectRef object
) const
255 // FIXME We can't use C API function JSObjectGetPropertyNames as it returns only enumerable properties.
256 return m_originalGlobalObject
.objectGetOwnPropertyNames(object
);