summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/qt/api
diff options
context:
space:
mode:
Diffstat (limited to 'JavaScriptCore/qt/api')
-rw-r--r--JavaScriptCore/qt/api/QtScript.pro3
-rw-r--r--JavaScriptCore/qt/api/qscriptengine.cpp107
-rw-r--r--JavaScriptCore/qt/api/qscriptengine.h11
-rw-r--r--JavaScriptCore/qt/api/qscriptengine_p.cpp36
-rw-r--r--JavaScriptCore/qt/api/qscriptengine_p.h7
-rw-r--r--JavaScriptCore/qt/api/qscriptfunction.cpp145
-rw-r--r--JavaScriptCore/qt/api/qscriptfunction_p.h57
-rw-r--r--JavaScriptCore/qt/api/qscriptoriginalglobalobject_p.h12
-rw-r--r--JavaScriptCore/qt/api/qscriptvalue_p.h48
9 files changed, 417 insertions, 9 deletions
diff --git a/JavaScriptCore/qt/api/QtScript.pro b/JavaScriptCore/qt/api/QtScript.pro
index c2c6f83..490758c 100644
--- a/JavaScriptCore/qt/api/QtScript.pro
+++ b/JavaScriptCore/qt/api/QtScript.pro
@@ -28,6 +28,7 @@ SOURCES += $$PWD/qscriptengine.cpp \
$$PWD/qscriptstring.cpp \
$$PWD/qscriptprogram.cpp \
$$PWD/qscriptsyntaxcheckresult.cpp \
+ $$PWD/qscriptfunction.cpp
HEADERS += $$PWD/qtscriptglobal.h \
$$PWD/qscriptengine.h \
@@ -43,7 +44,7 @@ HEADERS += $$PWD/qtscriptglobal.h \
$$PWD/qscriptprogram_p.h \
$$PWD/qscriptsyntaxcheckresult.h \
$$PWD/qscriptoriginalglobalobject_p.h \
-
+ $$PWD/qscriptfunction_p.h
!static: DEFINES += QT_MAKEDLL
diff --git a/JavaScriptCore/qt/api/qscriptengine.cpp b/JavaScriptCore/qt/api/qscriptengine.cpp
index 4b2319b..7ef7c8e 100644
--- a/JavaScriptCore/qt/api/qscriptengine.cpp
+++ b/JavaScriptCore/qt/api/qscriptengine.cpp
@@ -258,6 +258,93 @@ QScriptValue QScriptEngine::undefinedValue()
}
/*!
+ Creates a QScriptValue that wraps a native (C++) function. \a fun
+ must be a C++ function with signature QScriptEngine::FunctionSignature.
+ \a length is the number of arguments that \a fun expects; this becomes
+ the \c{length} property of the created QScriptValue.
+
+ Note that \a length only gives an indication of the number of
+ arguments that the function expects; an actual invocation of a
+ function can include any number of arguments. You can check the
+ \l{QScriptContext::argumentCount()}{argumentCount()} of the
+ QScriptContext associated with the invocation to determine the
+ actual number of arguments passed.
+
+ A \c{prototype} property is automatically created for the resulting
+ function object, to provide for the possibility that the function
+ will be used as a constructor.
+
+ By combining newFunction() and the property flags
+ QScriptValue::PropertyGetter and QScriptValue::PropertySetter, you
+ can create script object properties that behave like normal
+ properties in script code, but are in fact accessed through
+ functions (analogous to how properties work in \l{Qt's Property
+ System}). Example:
+
+ \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 11
+
+ When the property \c{foo} of the script object is subsequently
+ accessed in script code, \c{getSetFoo()} will be invoked to handle
+ the access. In this particular case, we chose to store the "real"
+ value of \c{foo} as a property of the accessor function itself; you
+ are of course free to do whatever you like in this function.
+
+ In the above example, a single native function was used to handle
+ both reads and writes to the property; the argument count is used to
+ determine if we are handling a read or write. You can also use two
+ separate functions; just specify the relevant flag
+ (QScriptValue::PropertyGetter or QScriptValue::PropertySetter) when
+ setting the property, e.g.:
+
+ \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 12
+
+ \sa QScriptValue::call()
+*/
+QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionSignature fun, int length)
+{
+ return QScriptValuePrivate::get(d_ptr->newFunction(fun, 0, length));
+}
+
+/*!
+ Creates a constructor function from \a fun, with the given \a length.
+ The \c{prototype} property of the resulting function is set to be the
+ given \a prototype. The \c{constructor} property of \a prototype is
+ set to be the resulting function.
+
+ When a function is called as a constructor (e.g. \c{new Foo()}), the
+ `this' object associated with the function call is the new object
+ that the function is expected to initialize; the prototype of this
+ default constructed object will be the function's public
+ \c{prototype} property. If you always want the function to behave as
+ a constructor (e.g. \c{Foo()} should also create a new object), or
+ if you need to create your own object rather than using the default
+ `this' object, you should make sure that the prototype of your
+ object is set correctly; either by setting it manually, or, when
+ wrapping a custom type, by having registered the defaultPrototype()
+ of that type. Example:
+
+ \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 9
+
+ To wrap a custom type and provide a constructor for it, you'd typically
+ do something like this:
+
+ \snippet doc/src/snippets/code/src_script_qscriptengine.cpp 10
+*/
+QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionSignature fun, const QScriptValue& prototype, int length)
+{
+ return QScriptValuePrivate::get(d_ptr->newFunction(fun, QScriptValuePrivate::get(prototype), length));
+}
+
+/*!
+ \internal
+ \since 4.4
+*/
+QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionWithArgSignature fun, void* arg)
+{
+ return QScriptValuePrivate::get(d_ptr->newFunction(fun, arg));
+}
+
+/*!
Creates a QtScript object of class Object.
The prototype of the created object will be the Object
@@ -294,3 +381,23 @@ QScriptValue QScriptEngine::globalObject() const
{
return QScriptValuePrivate::get(d_ptr->globalObject());
}
+
+/*!
+ \typedef QScriptEngine::FunctionSignature
+ \relates QScriptEngine
+
+ The function signature \c{QScriptValue f(QScriptContext *, QScriptEngine *)}.
+
+ A function with such a signature can be passed to
+ QScriptEngine::newFunction() to wrap the function.
+*/
+
+/*!
+ \typedef QScriptEngine::FunctionWithArgSignature
+ \relates QScriptEngine
+
+ The function signature \c{QScriptValue f(QScriptContext *, QScriptEngine *, void *)}.
+
+ A function with such a signature can be passed to
+ QScriptEngine::newFunction() to wrap the function.
+*/
diff --git a/JavaScriptCore/qt/api/qscriptengine.h b/JavaScriptCore/qt/api/qscriptengine.h
index 1a87a37..b85dc52 100644
--- a/JavaScriptCore/qt/api/qscriptengine.h
+++ b/JavaScriptCore/qt/api/qscriptengine.h
@@ -30,6 +30,9 @@
class QScriptValue;
class QScriptEnginePrivate;
+// FIXME: Remove this once QScriptContext is properly defined.
+typedef void QScriptContext;
+
// Internal typedef
typedef QExplicitlySharedDataPointer<QScriptEnginePrivate> QScriptEnginePtr;
@@ -56,6 +59,14 @@ public:
QScriptValue nullValue();
QScriptValue undefinedValue();
+
+ typedef QScriptValue (*FunctionSignature)(QScriptContext *, QScriptEngine *);
+ typedef QScriptValue (*FunctionWithArgSignature)(QScriptContext *, QScriptEngine *, void *);
+
+ QScriptValue newFunction(FunctionSignature fun, int length = 0);
+ QScriptValue newFunction(FunctionSignature fun, const QScriptValue& prototype, int length = 0);
+ QScriptValue newFunction(FunctionWithArgSignature fun, void* arg);
+
QScriptValue newObject();
QScriptValue newArray(uint length = 0);
QScriptValue globalObject() const;
diff --git a/JavaScriptCore/qt/api/qscriptengine_p.cpp b/JavaScriptCore/qt/api/qscriptengine_p.cpp
index e3311ed..a708a34 100644
--- a/JavaScriptCore/qt/api/qscriptengine_p.cpp
+++ b/JavaScriptCore/qt/api/qscriptengine_p.cpp
@@ -21,6 +21,7 @@
#include "qscriptengine_p.h"
+#include "qscriptfunction_p.h"
#include "qscriptprogram_p.h"
#include "qscriptvalue_p.h"
@@ -33,11 +34,15 @@ QScriptEnginePrivate::QScriptEnginePrivate(const QScriptEngine* engine)
, m_context(JSGlobalContextCreate(0))
, m_exception(0)
, m_originalGlobalObject(m_context)
+ , m_nativeFunctionClass(JSClassCreate(&qt_NativeFunctionClass))
+ , m_nativeFunctionWithArgClass(JSClassCreate(&qt_NativeFunctionWithArgClass))
{
}
QScriptEnginePrivate::~QScriptEnginePrivate()
{
+ JSClassRelease(m_nativeFunctionClass);
+ JSClassRelease(m_nativeFunctionWithArgClass);
if (m_exception)
JSValueUnprotect(m_context, m_exception);
JSGlobalContextRelease(m_context);
@@ -86,6 +91,37 @@ QScriptValuePrivate* QScriptEnginePrivate::uncaughtException() const
return m_exception ? new QScriptValuePrivate(this, m_exception) : new QScriptValuePrivate();
}
+QScriptValuePrivate* QScriptEnginePrivate::newFunction(QScriptEngine::FunctionSignature fun, QScriptValuePrivate* prototype, int length)
+{
+ // Note that this private data will be deleted in the object finalize function.
+ QNativeFunctionData* data = new QNativeFunctionData(this, fun);
+ JSObjectRef funJS = JSObjectMake(m_context, m_nativeFunctionClass, reinterpret_cast<void*>(data));
+ QScriptValuePrivate* proto = prototype ? prototype : newObject();
+ return newFunction(funJS, proto);
+}
+
+QScriptValuePrivate* QScriptEnginePrivate::newFunction(QScriptEngine::FunctionWithArgSignature fun, void* arg)
+{
+ // Note that this private data will be deleted in the object finalize function.
+ QNativeFunctionWithArgData* data = new QNativeFunctionWithArgData(this, fun, arg);
+ JSObjectRef funJS = JSObjectMake(m_context, m_nativeFunctionWithArgClass, reinterpret_cast<void*>(data));
+ QScriptValuePrivate* proto = newObject();
+ return newFunction(funJS, proto);
+}
+
+QScriptValuePrivate* QScriptEnginePrivate::newFunction(JSObjectRef funJS, QScriptValuePrivate* prototype)
+{
+ JSObjectSetPrototype(m_context, funJS, m_originalGlobalObject.functionPrototype());
+
+ QScriptValuePrivate* result = new QScriptValuePrivate(this, funJS);
+ static JSStringRef protoName = QScriptConverter::toString("prototype");
+ static JSStringRef constructorName = QScriptConverter::toString("constructor");
+ result->setProperty(protoName, prototype, QScriptValue::Undeletable);
+ prototype->setProperty(constructorName, result, QScriptValue::PropertyFlags(QScriptValue::Undeletable | QScriptValue::SkipInEnumeration));
+
+ return result;
+}
+
QScriptValuePrivate* QScriptEnginePrivate::newObject() const
{
return new QScriptValuePrivate(this, JSObjectMake(m_context, /* jsClass */ 0, /* userData */ 0));
diff --git a/JavaScriptCore/qt/api/qscriptengine_p.h b/JavaScriptCore/qt/api/qscriptengine_p.h
index d54cdcc..eec1929 100644
--- a/JavaScriptCore/qt/api/qscriptengine_p.h
+++ b/JavaScriptCore/qt/api/qscriptengine_p.h
@@ -71,6 +71,10 @@ public:
inline JSValueRef makeJSValue(bool number) const;
inline JSValueRef makeJSValue(QScriptValue::SpecialValue value) const;
+ QScriptValuePrivate* newFunction(QScriptEngine::FunctionSignature fun, QScriptValuePrivate* prototype, int length);
+ QScriptValuePrivate* newFunction(QScriptEngine::FunctionWithArgSignature fun, void* arg);
+ QScriptValuePrivate* newFunction(JSObjectRef funObject, QScriptValuePrivate* prototype);
+
QScriptValuePrivate* newObject() const;
QScriptValuePrivate* newArray(uint length);
QScriptValuePrivate* globalObject() const;
@@ -89,6 +93,9 @@ private:
JSValueRef m_exception;
QScriptOriginalGlobalObject m_originalGlobalObject;
+
+ JSClassRef m_nativeFunctionClass;
+ JSClassRef m_nativeFunctionWithArgClass;
};
diff --git a/JavaScriptCore/qt/api/qscriptfunction.cpp b/JavaScriptCore/qt/api/qscriptfunction.cpp
new file mode 100644
index 0000000..9fe37e6
--- /dev/null
+++ b/JavaScriptCore/qt/api/qscriptfunction.cpp
@@ -0,0 +1,145 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+// Contains the necessary helper structures to make possible expose
+// C/C++ functions to JavaScript environment.
+
+#include "config.h"
+
+#include "qscriptfunction_p.h"
+
+static void qt_NativeFunction_finalize(JSObjectRef object)
+{
+ void* priv = JSObjectGetPrivate(object);
+ delete reinterpret_cast<QNativeFunctionData*>(priv);
+}
+
+static JSValueRef qt_NativeFunction_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ QNativeFunctionData* data = reinterpret_cast<QNativeFunctionData*>(JSObjectGetPrivate(object));
+
+ // TODO: build a QScriptContext and use it in the native call.
+ QScriptContext* scriptContext = 0;
+ Q_UNUSED(context);
+ Q_UNUSED(thisObject);
+ Q_UNUSED(argumentCount);
+ Q_UNUSED(arguments);
+ Q_UNUSED(exception);
+
+ QScriptEnginePrivate* engine = data->engine;
+ QScriptValuePrivate* result = QScriptValuePrivate::get(data->fun(scriptContext, QScriptEnginePrivate::get(engine)));
+ if (!result->isValid()) {
+ qWarning("Invalid value returned from native function, returning undefined value instead.");
+ return engine->makeJSValue(QScriptValue::UndefinedValue);
+ }
+
+ // Make sure that the result will be assigned to the correct engine.
+ if (!result->engine()) {
+ Q_ASSERT(result->isValid());
+ result->assignEngine(engine);
+ } else if (result->engine() != engine) {
+ qWarning("Value from different engine returned from native function, returning undefined value instead.");
+ return engine->makeJSValue(QScriptValue::UndefinedValue);
+ }
+
+ return *result;
+}
+
+JSClassDefinition qt_NativeFunctionClass = {
+ 0, // version
+ kJSClassAttributeNoAutomaticPrototype, // attributes
+
+ "", // className
+ 0, // parentClass
+
+ 0, // staticValues
+ 0, // staticFunctions
+
+ 0, // initialize
+ qt_NativeFunction_finalize, // finalize
+ 0, // hasProperty
+ 0, // getProperty
+ 0, // setProperty
+ 0, // deleteProperty
+ 0, // getPropertyNames
+ qt_NativeFunction_callAsFunction, // callAsFunction
+ 0, // callAsConstructor
+ 0, // hasInstance
+ 0 // convertToType
+};
+
+static void qt_NativeFunctionWithArg_finalize(JSObjectRef object)
+{
+ void* priv = JSObjectGetPrivate(object);
+ delete reinterpret_cast<QNativeFunctionWithArgData*>(priv);
+}
+
+static JSValueRef qt_NativeFunctionWithArg_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+ QNativeFunctionWithArgData* data = reinterpret_cast<QNativeFunctionWithArgData*>(JSObjectGetPrivate(object));
+
+ // TODO: build a QScriptContext and use it in the native call.
+ QScriptContext* scriptContext = 0;
+ Q_UNUSED(context);
+ Q_UNUSED(thisObject);
+ Q_UNUSED(argumentCount);
+ Q_UNUSED(arguments);
+ Q_UNUSED(exception);
+
+ QScriptEnginePrivate* engine = data->engine;
+ QScriptValuePrivate* result = QScriptValuePrivate::get(data->fun(scriptContext, QScriptEnginePrivate::get(engine), data->arg));
+ if (!result->isValid()) {
+ qWarning("Invalid value returned from native function, returning undefined value instead.");
+ return engine->makeJSValue(QScriptValue::UndefinedValue);
+ }
+
+ // Make sure that the result will be assigned to the correct engine.
+ if (!result->engine()) {
+ Q_ASSERT(result->isValid());
+ result->assignEngine(engine);
+ } else if (result->engine() != engine) {
+ qWarning("Value from different engine returned from native function, returning undefined value instead.");
+ return engine->makeJSValue(QScriptValue::UndefinedValue);
+ }
+
+ return *result;
+}
+
+JSClassDefinition qt_NativeFunctionWithArgClass = {
+ 0, // version
+ kJSClassAttributeNoAutomaticPrototype, // attributes
+
+ "", // className
+ 0, // parentClass
+
+ 0, // staticValues
+ 0, // staticFunctions
+
+ 0, // initialize
+ qt_NativeFunctionWithArg_finalize, // finalize
+ 0, // hasProperty
+ 0, // getProperty
+ 0, // setProperty
+ 0, // deleteProperty
+ 0, // getPropertyNames
+ qt_NativeFunctionWithArg_callAsFunction, // callAsFunction
+ 0, // callAsConstructor
+ 0, // hasInstance
+ 0 // convertToType
+};
diff --git a/JavaScriptCore/qt/api/qscriptfunction_p.h b/JavaScriptCore/qt/api/qscriptfunction_p.h
new file mode 100644
index 0000000..65b6046
--- /dev/null
+++ b/JavaScriptCore/qt/api/qscriptfunction_p.h
@@ -0,0 +1,57 @@
+/*
+ Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef qscriptfunction_p_h
+#define qscriptfunction_p_h
+
+#include "config.h"
+
+#include "qscriptengine.h"
+#include "qscriptvalue_p.h"
+
+extern JSClassDefinition qt_NativeFunctionClass;
+extern JSClassDefinition qt_NativeFunctionWithArgClass;
+
+struct QNativeFunctionData
+{
+ QNativeFunctionData(QScriptEnginePrivate* engine, QScriptEngine::FunctionSignature fun)
+ : engine(engine)
+ , fun(fun)
+ {
+ }
+
+ QScriptEnginePrivate* engine;
+ QScriptEngine::FunctionSignature fun;
+};
+
+struct QNativeFunctionWithArgData
+{
+ QNativeFunctionWithArgData(QScriptEnginePrivate* engine, QScriptEngine::FunctionWithArgSignature fun, void* arg)
+ : engine(engine)
+ , fun(fun)
+ , arg(arg)
+ {
+ }
+
+ QScriptEnginePrivate* engine;
+ QScriptEngine::FunctionWithArgSignature fun;
+ void* arg;
+};
+
+#endif
diff --git a/JavaScriptCore/qt/api/qscriptoriginalglobalobject_p.h b/JavaScriptCore/qt/api/qscriptoriginalglobalobject_p.h
index 8d080fb..31e94f7 100644
--- a/JavaScriptCore/qt/api/qscriptoriginalglobalobject_p.h
+++ b/JavaScriptCore/qt/api/qscriptoriginalglobalobject_p.h
@@ -45,6 +45,8 @@ public:
inline bool isArray(JSValueRef value) const;
inline bool isError(JSValueRef value) const;
+
+ inline JSValueRef functionPrototype() const;
private:
inline bool isType(JSValueRef value, JSObjectRef constructor, JSValueRef prototype) const;
inline void initializeMember(JSObjectRef globalObject, JSStringRef prototypeName, const char* type, JSObjectRef& constructor, JSValueRef& prototype);
@@ -57,6 +59,8 @@ private:
JSValueRef m_arrayPrototype;
JSObjectRef m_errorConstructor;
JSValueRef m_errorPrototype;
+ JSObjectRef m_functionConstructor;
+ JSValueRef m_functionPrototype;
// Reference to standard JS functions that are not exposed by JSC C API.
JSObjectRef m_hasOwnPropertyFunction;
@@ -73,6 +77,7 @@ QScriptOriginalGlobalObject::QScriptOriginalGlobalObject(JSGlobalContextRef cont
propertyName.adopt(JSStringCreateWithUTF8CString("prototype"));
initializeMember(globalObject, propertyName.get(), "Array", m_arrayConstructor, m_arrayPrototype);
initializeMember(globalObject, propertyName.get(), "Error", m_errorConstructor, m_errorPrototype);
+ initializeMember(globalObject, propertyName.get(), "Function", m_functionConstructor, m_functionPrototype);
propertyName.adopt(JSStringCreateWithUTF8CString("hasOwnProperty"));
m_hasOwnPropertyFunction = const_cast<JSObjectRef>(JSObjectGetProperty(m_context, globalObject, propertyName.get(), &exception));
@@ -119,6 +124,8 @@ QScriptOriginalGlobalObject::~QScriptOriginalGlobalObject()
JSValueUnprotect(m_context, m_arrayPrototype);
JSValueUnprotect(m_context, m_errorConstructor);
JSValueUnprotect(m_context, m_errorPrototype);
+ JSValueUnprotect(m_context, m_functionConstructor);
+ JSValueUnprotect(m_context, m_functionPrototype);
JSValueUnprotect(m_context, m_hasOwnPropertyFunction);
JSValueUnprotect(m_context, m_getOwnPropertyNamesFunction);
JSGlobalContextRelease(m_context);
@@ -173,6 +180,11 @@ inline bool QScriptOriginalGlobalObject::isError(JSValueRef value) const
return isType(value, m_errorConstructor, m_errorPrototype);
}
+inline JSValueRef QScriptOriginalGlobalObject::functionPrototype() const
+{
+ return m_functionPrototype;
+}
+
inline bool QScriptOriginalGlobalObject::isType(JSValueRef value, JSObjectRef constructor, JSValueRef prototype) const
{
// JSC API doesn't export the [[Class]] information for the builtins. But we know that a value
diff --git a/JavaScriptCore/qt/api/qscriptvalue_p.h b/JavaScriptCore/qt/api/qscriptvalue_p.h
index 6e93a07..6fbf98b 100644
--- a/JavaScriptCore/qt/api/qscriptvalue_p.h
+++ b/JavaScriptCore/qt/api/qscriptvalue_p.h
@@ -699,16 +699,48 @@ bool QScriptValuePrivate::equals(QScriptValuePrivate* other)
if (!other->isValid())
return false;
- if ((m_state == other->m_state) && !isJSBased()) {
- if (isNumberBased())
- return u.m_number == other->u.m_number;
- Q_ASSERT(isStringBased());
- return *u.m_string == *(other->u.m_string);
+ 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, "equals()", "Not all states are included in the previous switch statement.");
+ }
}
- if (!isJSBased() && !other->isJSBased())
- return false;
-
if (isJSBased() && !other->isJSBased()) {
if (!other->assignEngine(engine())) {
qWarning("equals(): Cannot compare to a value created in a different engine");