summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/qt/api/qscriptvalue_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'JavaScriptCore/qt/api/qscriptvalue_p.h')
-rw-r--r--JavaScriptCore/qt/api/qscriptvalue_p.h96
1 files changed, 54 insertions, 42 deletions
diff --git a/JavaScriptCore/qt/api/qscriptvalue_p.h b/JavaScriptCore/qt/api/qscriptvalue_p.h
index 8db43a7..830b38e 100644
--- a/JavaScriptCore/qt/api/qscriptvalue_p.h
+++ b/JavaScriptCore/qt/api/qscriptvalue_p.h
@@ -38,10 +38,10 @@ class QScriptValue;
Implementation of QScriptValue.
The implementation is based on a state machine. The states names are included in
- QScriptValuePrivate::States. Each method should check for the current state and then perform a
+ QScriptValuePrivate::State. Each method should check for the current state and then perform a
correct action.
- States:
+ State:
Invalid -> QSVP is invalid, no assumptions should be made about class members (apart from m_value).
CString -> QSVP is created from QString or const char* and no JSC engine has been associated yet.
Current value is kept in m_string,
@@ -53,7 +53,7 @@ class QScriptValue;
is kept in m_number (cast of QScriptValue::SpecialValue)
JSValue -> QSVP is associated with engine, but there is no information about real type, the state
have really short live cycle. Normally it is created as a function call result.
- JSNative -> QSVP is associated with engine, and it is sure that it isn't a JavaScript object.
+ JSPrimitive -> QSVP is associated with engine, and it is sure that it isn't a JavaScript object.
JSObject -> QSVP is associated with engine, and it is sure that it is a JavaScript object.
Each state keep all necessary information to invoke all methods, if not it should be changed to
@@ -117,14 +117,14 @@ public:
private:
// Please, update class documentation when you change the enum.
- enum States {
+ enum State {
Invalid = 0,
CString = 0x1000,
CNumber,
CBool,
CSpecial,
JSValue = 0x2000, // JS values are equal or higher then this value.
- JSNative,
+ JSPrimitive,
JSObject
} m_state;
QScriptEnginePtr m_engine;
@@ -136,6 +136,7 @@ private:
inline void setValue(JSValueRef);
inline bool inherits(const char*);
+ inline State refinedJSValue();
inline bool isJSBased() const;
inline bool isNumberBased() const;
@@ -209,7 +210,7 @@ QScriptValuePrivate::QScriptValuePrivate(QScriptValue::SpecialValue value)
}
QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, bool value)
- : m_state(JSNative)
+ : m_state(JSPrimitive)
{
if (!engine) {
// slower path reinitialization
@@ -224,7 +225,7 @@ QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, bool value
}
QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, int value)
- : m_state(JSNative)
+ : m_state(JSPrimitive)
{
if (!engine) {
// slower path reinitialization
@@ -239,7 +240,7 @@ QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, int value)
}
QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, uint value)
- : m_state(JSNative)
+ : m_state(JSPrimitive)
{
if (!engine) {
// slower path reinitialization
@@ -254,7 +255,7 @@ QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, uint value
}
QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, qsreal value)
- : m_state(JSNative)
+ : m_state(JSPrimitive)
{
if (!engine) {
// slower path reinitialization
@@ -269,7 +270,7 @@ QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, qsreal val
}
QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, const QString& value)
- : m_state(JSNative)
+ : m_state(JSPrimitive)
{
if (!engine) {
// slower path reinitialization
@@ -284,7 +285,7 @@ QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, const QStr
}
QScriptValuePrivate::QScriptValuePrivate(const QScriptEngine* engine, QScriptValue::SpecialValue value)
- : m_state(JSNative)
+ : m_state(JSPrimitive)
{
if (!engine) {
// slower path reinitialization
@@ -325,10 +326,10 @@ bool QScriptValuePrivate::isBool()
case CBool:
return true;
case JSValue:
- if (isObject())
+ if (refinedJSValue() != JSPrimitive)
return false;
// Fall-through.
- case JSNative:
+ case JSPrimitive:
return JSValueIsBoolean(context(), value());
default:
return false;
@@ -341,10 +342,10 @@ bool QScriptValuePrivate::isNumber()
case CNumber:
return true;
case JSValue:
- if (isObject())
+ if (refinedJSValue() != JSPrimitive)
return false;
// Fall-through.
- case JSNative:
+ case JSPrimitive:
return JSValueIsNumber(context(), value());
default:
return false;
@@ -357,10 +358,10 @@ bool QScriptValuePrivate::isNull()
case CSpecial:
return m_number == static_cast<int>(QScriptValue::NullValue);
case JSValue:
- if (isObject())
+ if (refinedJSValue() != JSPrimitive)
return false;
// Fall-through.
- case JSNative:
+ case JSPrimitive:
return JSValueIsNull(context(), value());
default:
return false;
@@ -373,10 +374,10 @@ bool QScriptValuePrivate::isString()
case CString:
return true;
case JSValue:
- if (isObject())
+ if (refinedJSValue() != JSPrimitive)
return false;
// Fall-through.
- case JSNative:
+ case JSPrimitive:
return JSValueIsString(context(), value());
default:
return false;
@@ -389,10 +390,10 @@ bool QScriptValuePrivate::isUndefined()
case CSpecial:
return m_number == static_cast<int>(QScriptValue::UndefinedValue);
case JSValue:
- if (isObject())
+ if (refinedJSValue() != JSPrimitive)
return false;
// Fall-through.
- case JSNative:
+ case JSPrimitive:
return JSValueIsUndefined(context(), value());
default:
return false;
@@ -403,7 +404,7 @@ bool QScriptValuePrivate::isError()
{
switch (m_state) {
case JSValue:
- if (!isObject())
+ if (refinedJSValue() != JSObject)
return false;
// Fall-through.
case JSObject:
@@ -416,14 +417,11 @@ bool QScriptValuePrivate::isError()
bool QScriptValuePrivate::isObject()
{
switch (m_state) {
- case JSObject:
- return true;
case JSValue:
- m_object = JSValueToObject(context(), value(), /* exception */ 0);
- if (!m_object)
- return false;
- m_state = JSObject;
+ return refinedJSValue() == JSObject;
+ case JSObject:
return true;
+
default:
return false;
}
@@ -433,10 +431,8 @@ bool QScriptValuePrivate::isFunction()
{
switch (m_state) {
case JSValue:
- m_object = JSValueToObject(context(), value(), /* exception */ 0);
- if (!m_object)
+ if (refinedJSValue() != JSObject)
return false;
- m_state = JSObject;
// Fall-through.
case JSObject:
return JSObjectIsFunction(context(), object());
@@ -455,11 +451,11 @@ QString QScriptValuePrivate::toString() const
case CString:
return m_string;
case CNumber:
- return QString::number(m_number);
+ return QScriptConverter::toString(m_number);
case CSpecial:
return m_number == QScriptValue::NullValue ? QString::fromLatin1("null") : QString::fromLatin1("undefined");
case JSValue:
- case JSNative:
+ case JSPrimitive:
case JSObject:
return QScriptConverter::toString(JSValueToStringCopy(context(), value(), /* exception */ 0));
}
@@ -472,7 +468,7 @@ qsreal QScriptValuePrivate::toNumber() const
{
switch (m_state) {
case JSValue:
- case JSNative:
+ case JSPrimitive:
case JSObject:
return JSValueToNumber(context(), value(), /* exception */ 0);
case CNumber:
@@ -504,7 +500,7 @@ bool QScriptValuePrivate::toBool() const
{
switch (m_state) {
case JSValue:
- case JSNative:
+ case JSPrimitive:
return JSValueToBoolean(context(), value());
case JSObject:
return true;
@@ -631,7 +627,7 @@ bool QScriptValuePrivate::assignEngine(QScriptEnginePrivate* engine)
return false;
}
m_engine = engine;
- m_state = JSNative;
+ m_state = JSPrimitive;
setValue(value);
return true;
}
@@ -640,12 +636,8 @@ QScriptValuePrivate* QScriptValuePrivate::call(const QScriptValuePrivate*, const
{
switch (m_state) {
case JSValue:
- m_object = JSValueToObject(context(), value(), /* exception */ 0);
- if (!object()) {
- m_state = JSValue;
+ if (refinedJSValue() != JSObject)
return new QScriptValuePrivate;
- }
- m_state = JSObject;
// Fall-through.
case JSObject:
{
@@ -719,12 +711,32 @@ bool QScriptValuePrivate::inherits(const char* name)
{
Q_ASSERT(isJSBased());
JSObjectRef globalObject = JSContextGetGlobalObject(context());
- JSValueRef error = JSObjectGetProperty(context(), globalObject, QScriptConverter::toString(name), 0);
+ JSStringRef errorAttrName = QScriptConverter::toString(name);
+ JSValueRef error = JSObjectGetProperty(context(), globalObject, errorAttrName, /* exception */ 0);
+ JSStringRelease(errorAttrName);
return JSValueIsInstanceOfConstructor(context(), value(), JSValueToObject(context(), error, /* exception */ 0), /* exception */ 0);
}
/*!
\internal
+ Refines the state of this QScriptValuePrivate. Returns the new state.
+*/
+QScriptValuePrivate::State QScriptValuePrivate::refinedJSValue()
+{
+ Q_ASSERT(m_state == JSValue);
+ if (!JSValueIsObject(context(), value())) {
+ m_state = JSPrimitive;
+ } else {
+ m_state = JSObject;
+ // We are sure that value is an JSObject, so we can const_cast safely without
+ // calling JSC C API (JSValueToObject(context(), value(), /* exceptions */ 0)).
+ m_object = const_cast<JSObjectRef>(m_value);
+ }
+ return m_state;
+}
+
+/*!
+ \internal
Returns true if QSV have an engine associated.
*/
bool QScriptValuePrivate::isJSBased() const { return m_state >= JSValue; }