diff options
author | Kent Hansen <kent.hansen@nokia.com> | 2010-02-11 10:55:52 (GMT) |
---|---|---|
committer | Kent Hansen <kent.hansen@nokia.com> | 2010-03-10 09:19:43 (GMT) |
commit | d73e11d56a094544f036fac3f6e4483d1104261e (patch) | |
tree | c292c8f53c660dae3f7681dc7acbbe788730a580 /src/script/bridge | |
parent | 20e2b87b5194abf7e9f08b7c42c030a57e2d6b28 (diff) | |
download | Qt-d73e11d56a094544f036fac3f6e4483d1104261e.zip Qt-d73e11d56a094544f036fac3f6e4483d1104261e.tar.gz Qt-d73e11d56a094544f036fac3f6e4483d1104261e.tar.bz2 |
Update src/3rdparty/javascriptcore and adapt src/script to the changes
- Update qscriptvalueiterator test to expect length property when
iterating arrays and strings.
- Use EvalExecutable::create() instead of EvalExecutable constructor.
The constructor is private.
- Reimplement getOwnPropertyDescriptor() in all custom script objects.
- Remove all reimplementations of getPropertyAttributes().
It doesn't exist in trunk anymore (getOwnPropertyDescriptor() is used
instead).
- Remove checkDontDelete argument from deleteProperty() reimplementations.
The purpose of this argument was to support deleting properties
with attribute Undeletable from C++. But it was quite an invasive
patch to JavaScriptCore, and it doesn't seem worth it. If this feature
is really crucial it should be re-done upstream.
One of the tests needed to be updated so it's not sensitive to the
C++ undeletability.
- Adapt getOwnPropertyNames() reimplementations to signature change.
- Add missing QScriptObject structure flags, otherwise we don't get all virtual calls.
- Remove our patch for reporting column numbers in the debugger callbacks.
It was just too intrusive. As with the checkDontDelete issue, this should
be redone upstream if it's really important. In 4.7, QScriptEngineAgent
will always report a column number of 1.
Other compilation fixes:
- InternalFunction::name() takes an ExecState* argument, not GlobalData*
- ScopeChain::globalObject is no longer a function but a member variable
- ScopeChainNode constructor takes a GlobalObject argument
- Heap::collect() is called collectAllGarbage()
- JSValue::strictEqual() takes an ExecState* argument
- Debugger::exception() takes a bool hasHandler argument
- Debugger no longer reports column number (we decided to drop that patch from JSC)
- UString doesn't have operator+=(char*)
- Update the autotests to reflect the columnNumber=1 change.
- Add helper class to avoid crashing inside JSC.
Ever since r52856 in WebKit trunk, this is needed. There are probably a lot of
other public API functions that need this guard as well, but I'll add them as they
are discovered.
- Update mkdist-javascriptcore tag, exclude a few more files.
- Set ENABLE_JSC_MULTIPLE_THREADS=0 define on Mac due to r52355 in trunk.
Reviewed-by: Simon Hausmann
Diffstat (limited to 'src/script/bridge')
-rw-r--r-- | src/script/bridge/qscriptactivationobject.cpp | 18 | ||||
-rw-r--r-- | src/script/bridge/qscriptactivationobject_p.h | 6 | ||||
-rw-r--r-- | src/script/bridge/qscriptclassobject.cpp | 82 | ||||
-rw-r--r-- | src/script/bridge/qscriptclassobject_p.h | 11 | ||||
-rw-r--r-- | src/script/bridge/qscriptdeclarativeclass.cpp | 10 | ||||
-rw-r--r-- | src/script/bridge/qscriptdeclarativeclass_p.h | 3 | ||||
-rw-r--r-- | src/script/bridge/qscriptdeclarativeobject.cpp | 38 | ||||
-rw-r--r-- | src/script/bridge/qscriptdeclarativeobject_p.h | 8 | ||||
-rw-r--r-- | src/script/bridge/qscriptglobalobject.cpp | 38 | ||||
-rw-r--r-- | src/script/bridge/qscriptglobalobject_p.h | 25 | ||||
-rw-r--r-- | src/script/bridge/qscriptobject.cpp | 38 | ||||
-rw-r--r-- | src/script/bridge/qscriptobject_p.h | 18 | ||||
-rw-r--r-- | src/script/bridge/qscriptqobject.cpp | 156 | ||||
-rw-r--r-- | src/script/bridge/qscriptqobject_p.h | 22 | ||||
-rw-r--r-- | src/script/bridge/qscriptvariant.cpp | 7 |
15 files changed, 184 insertions, 296 deletions
diff --git a/src/script/bridge/qscriptactivationobject.cpp b/src/script/bridge/qscriptactivationobject.cpp index 7189f2e..6a8ae56 100644 --- a/src/script/bridge/qscriptactivationobject.cpp +++ b/src/script/bridge/qscriptactivationobject.cpp @@ -63,20 +63,20 @@ bool QScriptActivationObject::getOwnPropertySlot(JSC::ExecState* exec, const JSC return JSC::JSVariableObject::getOwnPropertySlot(exec, propertyName, slot); } -bool QScriptActivationObject::getPropertyAttributes(JSC::ExecState* exec, const JSC::Identifier& propertyName, unsigned& attributes) const +bool QScriptActivationObject::getOwnPropertyDescriptor(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::PropertyDescriptor& descriptor) { if (d_ptr()->delegate != 0) - return d_ptr()->delegate->getPropertyAttributes(exec, propertyName, attributes); - return JSC::JSVariableObject::getPropertyAttributes(exec, propertyName, attributes); + return d_ptr()->delegate->getOwnPropertyDescriptor(exec, propertyName, descriptor); + return JSC::JSVariableObject::getOwnPropertyDescriptor(exec, propertyName, descriptor); } -void QScriptActivationObject::getOwnPropertyNames(JSC::ExecState* exec, JSC::PropertyNameArray& propertyNames, bool includeNonEnumerable) +void QScriptActivationObject::getOwnPropertyNames(JSC::ExecState* exec, JSC::PropertyNameArray& propertyNames, JSC::EnumerationMode mode) { if (d_ptr()->delegate != 0) { - d_ptr()->delegate->getOwnPropertyNames(exec, propertyNames, includeNonEnumerable); + d_ptr()->delegate->getOwnPropertyNames(exec, propertyNames, mode); return; } - return JSC::JSVariableObject::getOwnPropertyNames(exec, propertyNames, includeNonEnumerable); + return JSC::JSVariableObject::getOwnPropertyNames(exec, propertyNames, mode); } void QScriptActivationObject::putWithAttributes(JSC::ExecState *exec, const JSC::Identifier &propertyName, JSC::JSValue value, unsigned attributes) @@ -111,11 +111,11 @@ void QScriptActivationObject::put(JSC::ExecState* exec, unsigned propertyName, J JSC::JSVariableObject::put(exec, propertyName, value); } -bool QScriptActivationObject::deleteProperty(JSC::ExecState* exec, const JSC::Identifier& propertyName, bool checkDontDelete) +bool QScriptActivationObject::deleteProperty(JSC::ExecState* exec, const JSC::Identifier& propertyName) { if (d_ptr()->delegate != 0) - return d_ptr()->delegate->deleteProperty(exec, propertyName, checkDontDelete); - return JSC::JSVariableObject::deleteProperty(exec, propertyName, checkDontDelete); + return d_ptr()->delegate->deleteProperty(exec, propertyName); + return JSC::JSVariableObject::deleteProperty(exec, propertyName); } void QScriptActivationObject::defineGetter(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction) diff --git a/src/script/bridge/qscriptactivationobject_p.h b/src/script/bridge/qscriptactivationobject_p.h index 7648a26..72ea11f 100644 --- a/src/script/bridge/qscriptactivationobject_p.h +++ b/src/script/bridge/qscriptactivationobject_p.h @@ -51,14 +51,14 @@ public: virtual bool isDynamicScope() const { return true; } virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertySlot&); - virtual bool getPropertyAttributes(JSC::ExecState*, const JSC::Identifier&, unsigned&) const; - virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, bool includeNonEnumerable = false); + virtual bool getOwnPropertyDescriptor(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertyDescriptor&); + virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, JSC::EnumerationMode mode = JSC::ExcludeDontEnumProperties); virtual void putWithAttributes(JSC::ExecState *exec, const JSC::Identifier &propertyName, JSC::JSValue value, unsigned attributes); virtual void put(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSValue value, JSC::PutPropertySlot&); virtual void put(JSC::ExecState*, unsigned propertyName, JSC::JSValue value); - virtual bool deleteProperty(JSC::ExecState*, const JSC::Identifier& propertyName, bool checkDontDelete = true); + virtual bool deleteProperty(JSC::ExecState*, const JSC::Identifier& propertyName); virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction); virtual void defineSetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction); diff --git a/src/script/bridge/qscriptclassobject.cpp b/src/script/bridge/qscriptclassobject.cpp index ce0a08e..a7b5f48 100644 --- a/src/script/bridge/qscriptclassobject.cpp +++ b/src/script/bridge/qscriptclassobject.cpp @@ -84,6 +84,47 @@ bool ClassObjectDelegate::getOwnPropertySlot(QScriptObject* object, return false; } +bool ClassObjectDelegate::getOwnPropertyDescriptor(QScriptObject *object, + JSC::ExecState *exec, + const JSC::Identifier &propertyName, + JSC::PropertyDescriptor &descriptor) +{ + QScriptEnginePrivate *engine = scriptEngineFromExec(exec); + QScript::SaveFrameHelper saveFrame(engine, exec); + // for compatibility with the old back-end, normal JS properties + // are queried first. + if (QScriptObjectDelegate::getOwnPropertyDescriptor(object, exec, propertyName, descriptor)) + return true; + + QScriptValue scriptObject = engine->scriptValueFromJSCValue(object); + QScriptString scriptName; + QScriptStringPrivate scriptName_d(engine, propertyName, QScriptStringPrivate::StackAllocated); + QScriptStringPrivate::init(scriptName, &scriptName_d); + uint id = 0; + QScriptClass::QueryFlags qflags = m_scriptClass->queryProperty( + scriptObject, scriptName, QScriptClass::HandlesReadAccess, &id); + if (qflags & QScriptClass::HandlesReadAccess) { + QScriptValue::PropertyFlags pflags = m_scriptClass->propertyFlags(scriptObject, scriptName, id); + unsigned attribs = 0; + if (pflags & QScriptValue::ReadOnly) + attribs |= JSC::ReadOnly; + if (pflags & QScriptValue::SkipInEnumeration) + attribs |= JSC::DontEnum; + if (pflags & QScriptValue::Undeletable) + attribs |= JSC::DontDelete; + if (pflags & QScriptValue::PropertyGetter) + attribs |= JSC::Getter; + if (pflags & QScriptValue::PropertySetter) + attribs |= JSC::Setter; + attribs |= pflags & QScriptValue::UserRange; + // Rather than calling the getter, we could return an access descriptor here. + QScriptValue value = m_scriptClass->property(scriptObject, scriptName, id); + descriptor.setDescriptor(engine->scriptValueToJSCValue(value), attribs); + return true; + } + return false; +} + void ClassObjectDelegate::put(QScriptObject* object, JSC::ExecState *exec, const JSC::Identifier &propertyName, JSC::JSValue value, JSC::PutPropertySlot &slot) @@ -105,8 +146,7 @@ void ClassObjectDelegate::put(QScriptObject* object, JSC::ExecState *exec, } bool ClassObjectDelegate::deleteProperty(QScriptObject* object, JSC::ExecState *exec, - const JSC::Identifier &propertyName, - bool checkDontDelete) + const JSC::Identifier &propertyName) { // ### avoid duplication of put() QScriptEnginePrivate *engine = scriptEngineFromExec(exec); @@ -124,44 +164,12 @@ bool ClassObjectDelegate::deleteProperty(QScriptObject* object, JSC::ExecState * m_scriptClass->setProperty(scriptObject, scriptName, id, QScriptValue()); return true; } - return QScriptObjectDelegate::deleteProperty(object, exec, propertyName, checkDontDelete); -} - -bool ClassObjectDelegate::getPropertyAttributes(const QScriptObject* object, JSC::ExecState *exec, - const JSC::Identifier &propertyName, - unsigned &attribs) const -{ - QScriptEnginePrivate *engine = scriptEngineFromExec(exec); - QScript::SaveFrameHelper saveFrame(engine, exec); - QScriptValue scriptObject = engine->scriptValueFromJSCValue(object); - QScriptString scriptName; - QScriptStringPrivate scriptName_d(engine, propertyName, QScriptStringPrivate::StackAllocated); - QScriptStringPrivate::init(scriptName, &scriptName_d); - uint id = 0; - QScriptClass::QueryFlags flags = m_scriptClass->queryProperty( - scriptObject, scriptName, QScriptClass::HandlesReadAccess, &id); - if (flags & QScriptClass::HandlesReadAccess) { - QScriptValue::PropertyFlags flags = m_scriptClass->propertyFlags(scriptObject, scriptName, id); - attribs = 0; - if (flags & QScriptValue::ReadOnly) - attribs |= JSC::ReadOnly; - if (flags & QScriptValue::SkipInEnumeration) - attribs |= JSC::DontEnum; - if (flags & QScriptValue::Undeletable) - attribs |= JSC::DontDelete; - if (flags & QScriptValue::PropertyGetter) - attribs |= JSC::Getter; - if (flags & QScriptValue::PropertySetter) - attribs |= JSC::Setter; - attribs |= flags & QScriptValue::UserRange; - return true; - } - return QScriptObjectDelegate::getPropertyAttributes(object, exec, propertyName, attribs); + return QScriptObjectDelegate::deleteProperty(object, exec, propertyName); } void ClassObjectDelegate::getOwnPropertyNames(QScriptObject* object, JSC::ExecState *exec, JSC::PropertyNameArray &propertyNames, - bool includeNonEnumerable) + JSC::EnumerationMode mode) { QScriptEnginePrivate *engine = scriptEngineFromExec(exec); QScript::SaveFrameHelper saveFrame(engine, exec); @@ -175,7 +183,7 @@ void ClassObjectDelegate::getOwnPropertyNames(QScriptObject* object, JSC::ExecSt } delete it; } - QScriptObjectDelegate::getOwnPropertyNames(object, exec, propertyNames, includeNonEnumerable); + QScriptObjectDelegate::getOwnPropertyNames(object, exec, propertyNames, mode); } JSC::CallType ClassObjectDelegate::getCallData(QScriptObject*, JSC::CallData &callData) diff --git a/src/script/bridge/qscriptclassobject_p.h b/src/script/bridge/qscriptclassobject_p.h index 89142ab..83fa61b 100644 --- a/src/script/bridge/qscriptclassobject_p.h +++ b/src/script/bridge/qscriptclassobject_p.h @@ -60,18 +60,17 @@ public: virtual bool getOwnPropertySlot(QScriptObject*, JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertySlot&); + virtual bool getOwnPropertyDescriptor(QScriptObject*, JSC::ExecState*, + const JSC::Identifier& propertyName, + JSC::PropertyDescriptor&); virtual void put(QScriptObject*, JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&); virtual bool deleteProperty(QScriptObject*, JSC::ExecState*, - const JSC::Identifier& propertyName, - bool checkDontDelete = true); - virtual bool getPropertyAttributes(const QScriptObject*, JSC::ExecState*, - const JSC::Identifier&, - unsigned&) const; + const JSC::Identifier& propertyName); virtual void getOwnPropertyNames(QScriptObject*, JSC::ExecState*, JSC::PropertyNameArray&, - bool includeNonEnumerable = false); + JSC::EnumerationMode mode = JSC::ExcludeDontEnumProperties); virtual JSC::CallType getCallData(QScriptObject*, JSC::CallData&); static JSC::JSValue JSC_HOST_CALL call(JSC::ExecState*, JSC::JSObject*, diff --git a/src/script/bridge/qscriptdeclarativeclass.cpp b/src/script/bridge/qscriptdeclarativeclass.cpp index 1d11ede..a753f59 100644 --- a/src/script/bridge/qscriptdeclarativeclass.cpp +++ b/src/script/bridge/qscriptdeclarativeclass.cpp @@ -141,19 +141,22 @@ QScriptValue QScriptDeclarativeClass::Value::toScriptValue(QScriptEngine *engine } QScriptDeclarativeClass::PersistentIdentifier::PersistentIdentifier() -: identifier(0) + : identifier(0), engine(0) { new (&d) JSC::Identifier(); } QScriptDeclarativeClass::PersistentIdentifier::~PersistentIdentifier() { + if (engine) + JSC::setCurrentIdentifierTable(engine->globalData->identifierTable); ((JSC::Identifier &)d).JSC::Identifier::~Identifier(); } QScriptDeclarativeClass::PersistentIdentifier::PersistentIdentifier(const PersistentIdentifier &other) { identifier = other.identifier; + engine = other.engine; new (&d) JSC::Identifier((JSC::Identifier &)(other.d)); } @@ -161,6 +164,7 @@ QScriptDeclarativeClass::PersistentIdentifier & QScriptDeclarativeClass::PersistentIdentifier::operator=(const PersistentIdentifier &other) { identifier = other.identifier; + engine = other.engine; ((JSC::Identifier &)d) = (JSC::Identifier &)(other.d); return *this; } @@ -419,7 +423,7 @@ QScriptDeclarativeClass::createPersistentIdentifier(const QString &str) static_cast<QScriptEnginePrivate *>(QObjectPrivate::get(d_ptr->engine)); JSC::ExecState* exec = p->currentFrame; - PersistentIdentifier rv(true); + PersistentIdentifier rv(p); new (&rv.d) JSC::Identifier(exec, (UChar *)str.constData(), str.size()); rv.identifier = (void *)((JSC::Identifier &)rv.d).ustring().rep(); return rv; @@ -432,7 +436,7 @@ QScriptDeclarativeClass::createPersistentIdentifier(const Identifier &id) static_cast<QScriptEnginePrivate *>(QObjectPrivate::get(d_ptr->engine)); JSC::ExecState* exec = p->currentFrame; - PersistentIdentifier rv(true); + PersistentIdentifier rv(p); new (&rv.d) JSC::Identifier(exec, (JSC::UString::Rep *)id); rv.identifier = (void *)((JSC::Identifier &)rv.d).ustring().rep(); return rv; diff --git a/src/script/bridge/qscriptdeclarativeclass_p.h b/src/script/bridge/qscriptdeclarativeclass_p.h index a0fd6d5..a187391 100644 --- a/src/script/bridge/qscriptdeclarativeclass_p.h +++ b/src/script/bridge/qscriptdeclarativeclass_p.h @@ -104,7 +104,8 @@ public: private: friend class QScriptDeclarativeClass; - PersistentIdentifier(bool) : identifier(0), d(0) {} + PersistentIdentifier(QScriptEnginePrivate *e) : identifier(0), engine(e), d(0) {} + QScriptEnginePrivate *engine; void *d; }; diff --git a/src/script/bridge/qscriptdeclarativeobject.cpp b/src/script/bridge/qscriptdeclarativeobject.cpp index c6ab6a7..a45bfbb 100644 --- a/src/script/bridge/qscriptdeclarativeobject.cpp +++ b/src/script/bridge/qscriptdeclarativeobject.cpp @@ -66,7 +66,6 @@ bool DeclarativeObjectDelegate::getOwnPropertySlot(QScriptObject* object, const JSC::Identifier &propertyName, JSC::PropertySlot &slot) { - QScriptEnginePrivate *engine = scriptEngineFromExec(exec); QScriptDeclarativeClass::Identifier identifier = (void *)propertyName.ustring().rep(); QScriptDeclarativeClassPrivate *p = QScriptDeclarativeClassPrivate::get(m_class); @@ -106,43 +105,14 @@ void DeclarativeObjectDelegate::put(QScriptObject* object, JSC::ExecState *exec, } bool DeclarativeObjectDelegate::deleteProperty(QScriptObject* object, JSC::ExecState *exec, - const JSC::Identifier &propertyName, - bool checkDontDelete) -{ - return QScriptObjectDelegate::deleteProperty(object, exec, propertyName, checkDontDelete); -} - -bool DeclarativeObjectDelegate::getPropertyAttributes(const QScriptObject* object, - JSC::ExecState *exec, - const JSC::Identifier &propertyName, - unsigned &attribs) const + const JSC::Identifier &propertyName) { - QScriptDeclarativeClass::Identifier identifier = (void *)propertyName.ustring().rep(); - - QScriptClass::QueryFlags flags = - m_class->queryProperty(m_object, identifier, QScriptClass::HandlesReadAccess); - if (flags & QScriptClass::HandlesReadAccess) { - QScriptValue::PropertyFlags flags = m_class->propertyFlags(m_object, identifier); - attribs = 0; - if (flags & QScriptValue::ReadOnly) - attribs |= JSC::ReadOnly; - if (flags & QScriptValue::SkipInEnumeration) - attribs |= JSC::DontEnum; - if (flags & QScriptValue::Undeletable) - attribs |= JSC::DontDelete; - if (flags & QScriptValue::PropertyGetter) - attribs |= JSC::Getter; - if (flags & QScriptValue::PropertySetter) - attribs |= JSC::Setter; - attribs |= flags & QScriptValue::UserRange; - return true; - } - return QScriptObjectDelegate::getPropertyAttributes(object, exec, propertyName, attribs); + return QScriptObjectDelegate::deleteProperty(object, exec, propertyName); } void DeclarativeObjectDelegate::getOwnPropertyNames(QScriptObject* object, JSC::ExecState *exec, JSC::PropertyNameArray &propertyNames, - bool includeNonEnumerable) + JSC::EnumerationMode mode) { QStringList properties = m_class->propertyNames(m_object); for (int ii = 0; ii < properties.count(); ++ii) { @@ -150,7 +120,7 @@ void DeclarativeObjectDelegate::getOwnPropertyNames(QScriptObject* object, JSC:: propertyNames.add(JSC::Identifier(exec, name)); } - QScriptObjectDelegate::getOwnPropertyNames(object, exec, propertyNames, includeNonEnumerable); + QScriptObjectDelegate::getOwnPropertyNames(object, exec, propertyNames, mode); } JSC::CallType DeclarativeObjectDelegate::getCallData(QScriptObject *object, JSC::CallData &callData) diff --git a/src/script/bridge/qscriptdeclarativeobject_p.h b/src/script/bridge/qscriptdeclarativeobject_p.h index ec8a43e..5024a71 100644 --- a/src/script/bridge/qscriptdeclarativeobject_p.h +++ b/src/script/bridge/qscriptdeclarativeobject_p.h @@ -81,14 +81,10 @@ public: const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&); virtual bool deleteProperty(QScriptObject*, JSC::ExecState*, - const JSC::Identifier& propertyName, - bool checkDontDelete = true); - virtual bool getPropertyAttributes(const QScriptObject*, JSC::ExecState*, - const JSC::Identifier&, - unsigned&) const; + const JSC::Identifier& propertyName); virtual void getOwnPropertyNames(QScriptObject*, JSC::ExecState*, JSC::PropertyNameArray&, - bool includeNonEnumerable = false); + JSC::EnumerationMode mode = JSC::ExcludeDontEnumProperties); virtual JSC::CallType getCallData(QScriptObject*, JSC::CallData&); static JSC::JSValue JSC_HOST_CALL call(JSC::ExecState*, JSC::JSObject*, diff --git a/src/script/bridge/qscriptglobalobject.cpp b/src/script/bridge/qscriptglobalobject.cpp index e7ea0df..4c002b7 100644 --- a/src/script/bridge/qscriptglobalobject.cpp +++ b/src/script/bridge/qscriptglobalobject.cpp @@ -72,6 +72,23 @@ bool GlobalObject::getOwnPropertySlot(JSC::ExecState* exec, return JSC::JSGlobalObject::getOwnPropertySlot(exec, propertyName, slot); } +bool GlobalObject::getOwnPropertyDescriptor(JSC::ExecState* exec, + const JSC::Identifier& propertyName, + JSC::PropertyDescriptor& descriptor) +{ + // Must match the logic of getOwnPropertySlot(). + QScriptEnginePrivate *engine = scriptEngineFromExec(exec); + if (propertyName == exec->propertyNames().arguments && engine->currentFrame->argumentCount() > 0) { + // ### Can we get rid of this special handling of the arguments property? + JSC::JSValue args = engine->scriptValueToJSCValue(engine->contextForFrame(engine->currentFrame)->argumentsObject()); + descriptor.setValue(args); + return true; + } + if (customGlobalObject) + return customGlobalObject->getOwnPropertyDescriptor(exec, propertyName, descriptor); + return JSC::JSGlobalObject::getOwnPropertyDescriptor(exec, propertyName, descriptor); +} + void GlobalObject::put(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSValue value, JSC::PutPropertySlot& slot) { @@ -90,29 +107,20 @@ void GlobalObject::putWithAttributes(JSC::ExecState* exec, const JSC::Identifier JSC::JSGlobalObject::putWithAttributes(exec, propertyName, value, attributes); } -bool GlobalObject::deleteProperty(JSC::ExecState* exec, - const JSC::Identifier& propertyName, bool checkDontDelete) -{ - if (customGlobalObject) - return customGlobalObject->deleteProperty(exec, propertyName, checkDontDelete); - return JSC::JSGlobalObject::deleteProperty(exec, propertyName, checkDontDelete); -} - -bool GlobalObject::getPropertyAttributes(JSC::ExecState* exec, const JSC::Identifier& propertyName, - unsigned& attributes) const +bool GlobalObject::deleteProperty(JSC::ExecState* exec, const JSC::Identifier& propertyName) { if (customGlobalObject) - return customGlobalObject->getPropertyAttributes(exec, propertyName, attributes); - return JSC::JSGlobalObject::getPropertyAttributes(exec, propertyName, attributes); + return customGlobalObject->deleteProperty(exec, propertyName); + return JSC::JSGlobalObject::deleteProperty(exec, propertyName); } void GlobalObject::getOwnPropertyNames(JSC::ExecState* exec, JSC::PropertyNameArray& propertyNames, - bool includeNonEnumerable) + JSC::EnumerationMode mode) { if (customGlobalObject) - customGlobalObject->getOwnPropertyNames(exec, propertyNames, includeNonEnumerable); + customGlobalObject->getOwnPropertyNames(exec, propertyNames, mode); else - JSC::JSGlobalObject::getOwnPropertyNames(exec, propertyNames, includeNonEnumerable); + JSC::JSGlobalObject::getOwnPropertyNames(exec, propertyNames, mode); } void GlobalObject::defineGetter(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction, unsigned attributes) diff --git a/src/script/bridge/qscriptglobalobject_p.h b/src/script/bridge/qscriptglobalobject_p.h index b210f78..c0a419f 100644 --- a/src/script/bridge/qscriptglobalobject_p.h +++ b/src/script/bridge/qscriptglobalobject_p.h @@ -54,17 +54,17 @@ public: virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertySlot&); + virtual bool getOwnPropertyDescriptor(JSC::ExecState*, + const JSC::Identifier& propertyName, + JSC::PropertyDescriptor&); virtual void put(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&); virtual void putWithAttributes(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSValue value, unsigned attributes); virtual bool deleteProperty(JSC::ExecState*, - const JSC::Identifier& propertyName, - bool checkDontDelete = true); - virtual bool getPropertyAttributes(JSC::ExecState*, const JSC::Identifier&, - unsigned&) const; + const JSC::Identifier& propertyName); virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, - bool includeNonEnumerable = false); + JSC::EnumerationMode mode = JSC::ExcludeDontEnumProperties); virtual void defineGetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction, unsigned attributes = 0); virtual void defineSetter(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction, unsigned attributes = 0); virtual JSC::JSValue lookupGetter(JSC::ExecState*, const JSC::Identifier& propertyName); @@ -94,19 +94,20 @@ public: const JSC::Identifier& propertyName, JSC::PropertySlot& slot) { return originalGlobalObject->JSC::JSGlobalObject::getOwnPropertySlot(exec, propertyName, slot); } + virtual bool getOwnPropertyDescriptor(JSC::ExecState* exec, + const JSC::Identifier& propertyName, + JSC::PropertyDescriptor& descriptor) + { return originalGlobalObject->JSC::JSGlobalObject::getOwnPropertyDescriptor(exec, propertyName, descriptor); } virtual void put(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSValue value, JSC::PutPropertySlot& slot) { originalGlobalObject->JSC::JSGlobalObject::put(exec, propertyName, value, slot); } virtual void putWithAttributes(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSValue value, unsigned attributes) { originalGlobalObject->JSC::JSGlobalObject::putWithAttributes(exec, propertyName, value, attributes); } virtual bool deleteProperty(JSC::ExecState* exec, - const JSC::Identifier& propertyName, bool checkDontDelete = true) - { return originalGlobalObject->JSC::JSGlobalObject::deleteProperty(exec, propertyName, checkDontDelete); } - virtual bool getPropertyAttributes(JSC::ExecState* exec, const JSC::Identifier& propertyName, - unsigned& attributes) const - { return originalGlobalObject->JSC::JSGlobalObject::getPropertyAttributes(exec, propertyName, attributes); } - virtual void getOwnPropertyNames(JSC::ExecState* exec, JSC::PropertyNameArray& propertyNames, bool includeNonEnumerable = false) - { originalGlobalObject->JSC::JSGlobalObject::getOwnPropertyNames(exec, propertyNames, includeNonEnumerable); } + const JSC::Identifier& propertyName) + { return originalGlobalObject->JSC::JSGlobalObject::deleteProperty(exec, propertyName); } + virtual void getOwnPropertyNames(JSC::ExecState* exec, JSC::PropertyNameArray& propertyNames, JSC::EnumerationMode mode = JSC::ExcludeDontEnumProperties) + { originalGlobalObject->JSC::JSGlobalObject::getOwnPropertyNames(exec, propertyNames, mode); } virtual void defineGetter(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSObject* getterFunction, unsigned attributes) { originalGlobalObject->JSC::JSGlobalObject::defineGetter(exec, propertyName, getterFunction, attributes); } virtual void defineSetter(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSObject* setterFunction, unsigned attributes) diff --git a/src/script/bridge/qscriptobject.cpp b/src/script/bridge/qscriptobject.cpp index 3db109e..9b6910e 100644 --- a/src/script/bridge/qscriptobject.cpp +++ b/src/script/bridge/qscriptobject.cpp @@ -81,30 +81,21 @@ void QScriptObject::put(JSC::ExecState* exec, const JSC::Identifier& propertyNam } bool QScriptObject::deleteProperty(JSC::ExecState* exec, - const JSC::Identifier& propertyName, - bool checkDontDelete) + const JSC::Identifier& propertyName) { if (!d || !d->delegate) - return JSC::JSObject::deleteProperty(exec, propertyName, checkDontDelete); - return d->delegate->deleteProperty(this, exec, propertyName, checkDontDelete); -} - -bool QScriptObject::getPropertyAttributes(JSC::ExecState* exec, const JSC::Identifier& propertyName, - unsigned& attributes) const -{ - if (!d || !d->delegate) - return JSC::JSObject::getPropertyAttributes(exec, propertyName, attributes); - return d->delegate->getPropertyAttributes(this, exec, propertyName, attributes); + return JSC::JSObject::deleteProperty(exec, propertyName); + return d->delegate->deleteProperty(this, exec, propertyName); } void QScriptObject::getOwnPropertyNames(JSC::ExecState* exec, JSC::PropertyNameArray& propertyNames, - bool includeNonEnumerable) + JSC::EnumerationMode mode) { if (!d || !d->delegate) { - JSC::JSObject::getOwnPropertyNames(exec, propertyNames, includeNonEnumerable); + JSC::JSObject::getOwnPropertyNames(exec, propertyNames, mode); return; } - d->delegate->getOwnPropertyNames(this, exec, propertyNames, includeNonEnumerable); + d->delegate->getOwnPropertyNames(this, exec, propertyNames, mode); } bool QScriptObject::compareToObject(JSC::ExecState* exec, JSC::JSObject *other) @@ -189,25 +180,16 @@ void QScriptObjectDelegate::put(QScriptObject* object, JSC::ExecState* exec, } bool QScriptObjectDelegate::deleteProperty(QScriptObject* object, JSC::ExecState* exec, - const JSC::Identifier& propertyName, - bool checkDontDelete) -{ - return object->JSC::JSObject::deleteProperty(exec, propertyName, checkDontDelete); -} - -bool QScriptObjectDelegate::getPropertyAttributes(const QScriptObject* object, - JSC::ExecState* exec, - const JSC::Identifier& propertyName, - unsigned& attributes) const + const JSC::Identifier& propertyName) { - return object->JSC::JSObject::getPropertyAttributes(exec, propertyName, attributes); + return object->JSC::JSObject::deleteProperty(exec, propertyName); } void QScriptObjectDelegate::getOwnPropertyNames(QScriptObject* object, JSC::ExecState* exec, JSC::PropertyNameArray& propertyNames, - bool includeNonEnumerable) + JSC::EnumerationMode mode) { - object->JSC::JSObject::getOwnPropertyNames(exec, propertyNames, includeNonEnumerable); + object->JSC::JSObject::getOwnPropertyNames(exec, propertyNames, mode); } void QScriptObjectDelegate::markChildren(QScriptObject* object, JSC::MarkStack& markStack) diff --git a/src/script/bridge/qscriptobject_p.h b/src/script/bridge/qscriptobject_p.h index 4d15bee..f6de418 100644 --- a/src/script/bridge/qscriptobject_p.h +++ b/src/script/bridge/qscriptobject_p.h @@ -67,12 +67,9 @@ public: virtual void put(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&); virtual bool deleteProperty(JSC::ExecState*, - const JSC::Identifier& propertyName, - bool checkDontDelete = true); - virtual bool getPropertyAttributes(JSC::ExecState*, const JSC::Identifier&, - unsigned&) const; + const JSC::Identifier& propertyName); virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, - bool includeNonEnumerable = false); + JSC::EnumerationMode mode = JSC::ExcludeDontEnumProperties); virtual void markChildren(JSC::MarkStack& markStack); virtual JSC::CallType getCallData(JSC::CallData&); virtual JSC::ConstructType getConstructData(JSC::ConstructData&); @@ -84,7 +81,7 @@ public: static WTF::PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype) { - return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, JSC::ImplementsHasInstance | JSC::OverridesHasInstance)); + return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags)); } inline JSC::JSValue data() const; @@ -94,6 +91,8 @@ public: inline void setDelegate(QScriptObjectDelegate *delegate); protected: + static const unsigned StructureFlags = JSC::ImplementsHasInstance | JSC::OverridesHasInstance | JSC::OverridesGetOwnPropertySlot | JSC::OverridesMarkChildren | JSC::OverridesGetPropertyNames | JSObject::StructureFlags; + Data *d; }; @@ -128,12 +127,9 @@ public: virtual void put(QScriptObject*, JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&); virtual bool deleteProperty(QScriptObject*, JSC::ExecState*, - const JSC::Identifier& propertyName, - bool checkDontDelete = true); - virtual bool getPropertyAttributes(const QScriptObject*, JSC::ExecState*, - const JSC::Identifier&, unsigned&) const; + const JSC::Identifier& propertyName); virtual void getOwnPropertyNames(QScriptObject*, JSC::ExecState*, JSC::PropertyNameArray&, - bool includeNonEnumerable = false); + JSC::EnumerationMode mode = JSC::ExcludeDontEnumProperties); virtual void markChildren(QScriptObject*, JSC::MarkStack& markStack); virtual JSC::CallType getCallData(QScriptObject*, JSC::CallData&); virtual JSC::ConstructType getConstructData(QScriptObject*, JSC::ConstructData&); diff --git a/src/script/bridge/qscriptqobject.cpp b/src/script/bridge/qscriptqobject.cpp index 6c401f8..a96d523 100644 --- a/src/script/bridge/qscriptqobject.cpp +++ b/src/script/bridge/qscriptqobject.cpp @@ -1298,7 +1298,7 @@ bool QObjectDelegate::getOwnPropertyDescriptor(QScriptObject *object, JSC::ExecS const JSC::Identifier &propertyName, JSC::PropertyDescriptor &descriptor) { - //Note: this has to be kept in sync with getOwnPropertySlot abd getPropertyAttributes + //Note: this has to be kept in sync with getOwnPropertySlot #ifndef QT_NO_PROPERTIES QByteArray name = convertToLatin1(propertyName.ustring()); QObject *qobject = data->value; @@ -1528,8 +1528,7 @@ void QObjectDelegate::put(QScriptObject *object, JSC::ExecState* exec, } bool QObjectDelegate::deleteProperty(QScriptObject *object, JSC::ExecState *exec, - const JSC::Identifier& propertyName, - bool checkDontDelete) + const JSC::Identifier& propertyName) { #ifndef QT_NO_PROPERTIES QByteArray name = convertToLatin1(propertyName.ustring()); @@ -1569,86 +1568,7 @@ bool QObjectDelegate::deleteProperty(QScriptObject *object, JSC::ExecState *exec return true; } - return QScriptObjectDelegate::deleteProperty(object, exec, propertyName, checkDontDelete); -#else //QT_NO_PROPERTIES - return false; -#endif //QT_NO_PROPERTIES -} - -bool QObjectDelegate::getPropertyAttributes(const QScriptObject *object, - JSC::ExecState *exec, - const JSC::Identifier &propertyName, - unsigned &attributes) const -{ -#ifndef QT_NO_PROPERTIES - //Note: this has to be kept in sync with getOwnPropertyDescriptor and getOwnPropertySlot - QByteArray name = convertToLatin1(propertyName.ustring()); - QObject *qobject = data->value; - if (!qobject) - return false; - - const QScriptEngine::QObjectWrapOptions &opt = data->options; - const QMetaObject *meta = qobject->metaObject(); - int index = -1; - if (name.contains('(')) { - QByteArray normalized = QMetaObject::normalizedSignature(name); - if (-1 != (index = meta->indexOfMethod(normalized))) { - QMetaMethod method = meta->method(index); - if (hasMethodAccess(method, index, opt)) { - if (!(opt & QScriptEngine::ExcludeSuperClassMethods) - || (index >= meta->methodOffset())) { - attributes = QObjectMemberAttribute; - if (opt & QScriptEngine::SkipMethodsInEnumeration) - attributes |= JSC::DontEnum; - return true; - } - } - } - } - - index = meta->indexOfProperty(name); - if (index != -1) { - QMetaProperty prop = meta->property(index); - if (prop.isScriptable()) { - if (!(opt & QScriptEngine::ExcludeSuperClassProperties) - || (index >= meta->propertyOffset())) { - attributes = flagsForMetaProperty(prop); - return true; - } - } - } - - index = qobject->dynamicPropertyNames().indexOf(name); - if (index != -1) { - attributes = QObjectMemberAttribute; - return true; - } - - const int offset = (opt & QScriptEngine::ExcludeSuperClassMethods) - ? meta->methodOffset() : 0; - for (index = meta->methodCount() - 1; index >= offset; --index) { - QMetaMethod method = meta->method(index); - if (hasMethodAccess(method, index, opt) - && methodNameEquals(method, name.constData(), name.length())) { - attributes = QObjectMemberAttribute; - if (opt & QScriptEngine::SkipMethodsInEnumeration) - attributes |= JSC::DontEnum; - return true; - } - } - - if (!(opt & QScriptEngine::ExcludeChildObjects)) { - QList<QObject*> children = qobject->children(); - for (index = 0; index < children.count(); ++index) { - QObject *child = children.at(index); - if (child->objectName() == (QString)(propertyName.ustring())) { - attributes = JSC::ReadOnly | JSC::DontDelete | JSC::DontEnum; - return true; - } - } - } - - return QScriptObjectDelegate::getPropertyAttributes(object, exec, propertyName, attributes); + return QScriptObjectDelegate::deleteProperty(object, exec, propertyName); #else //QT_NO_PROPERTIES return false; #endif //QT_NO_PROPERTIES @@ -1656,7 +1576,7 @@ bool QObjectDelegate::getPropertyAttributes(const QScriptObject *object, void QObjectDelegate::getOwnPropertyNames(QScriptObject *object, JSC::ExecState *exec, JSC::PropertyNameArray &propertyNames, - bool includeNonEnumerable) + JSC::EnumerationMode mode) { #ifndef QT_NO_PROPERTIES QObject *qobject = data->value; @@ -1701,7 +1621,7 @@ void QObjectDelegate::getOwnPropertyNames(QScriptObject *object, JSC::ExecState } } - QScriptObjectDelegate::getOwnPropertyNames(object, exec, propertyNames, includeNonEnumerable); + QScriptObjectDelegate::getOwnPropertyNames(object, exec, propertyNames, mode); #endif //QT_NO_PROPERTIES } @@ -1884,6 +1804,39 @@ bool QMetaObjectWrapperObject::getOwnPropertySlot( return JSC::JSObject::getOwnPropertySlot(exec, propertyName, slot); } +bool QMetaObjectWrapperObject::getOwnPropertyDescriptor( + JSC::ExecState* exec, const JSC::Identifier& propertyName, + JSC::PropertyDescriptor& descriptor) +{ + const QMetaObject *meta = data->value; + if (!meta) + return false; + + if (propertyName == exec->propertyNames().prototype) { + descriptor.setDescriptor(data->ctor + ? data->ctor.get(exec, propertyName) + : data->prototype, + JSC::DontDelete | JSC::DontEnum); + return true; + } + + QByteArray name = QString(propertyName.ustring()).toLatin1(); + + for (int i = 0; i < meta->enumeratorCount(); ++i) { + QMetaEnum e = meta->enumerator(i); + for (int j = 0; j < e.keyCount(); ++j) { + const char *key = e.key(j); + if (!qstrcmp(key, name.constData())) { + descriptor.setDescriptor(JSC::JSValue(exec, e.value(j)), + JSC::ReadOnly | JSC::DontDelete); + return true; + } + } + } + + return JSC::JSObject::getOwnPropertyDescriptor(exec, propertyName, descriptor); +} + void QMetaObjectWrapperObject::put(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSValue value, JSC::PutPropertySlot &slot) { @@ -1909,8 +1862,7 @@ void QMetaObjectWrapperObject::put(JSC::ExecState* exec, const JSC::Identifier& } bool QMetaObjectWrapperObject::deleteProperty( - JSC::ExecState *exec, const JSC::Identifier& propertyName, - bool checkDontDelete) + JSC::ExecState *exec, const JSC::Identifier& propertyName) { if (propertyName == exec->propertyNames().prototype) return false; @@ -1925,36 +1877,12 @@ bool QMetaObjectWrapperObject::deleteProperty( } } } - return JSC::JSObject::deleteProperty(exec, propertyName, checkDontDelete); -} - -bool QMetaObjectWrapperObject::getPropertyAttributes(JSC::ExecState *exec, - const JSC::Identifier &propertyName, - unsigned &attributes) const -{ - if (propertyName == exec->propertyNames().prototype) { - attributes = JSC::DontDelete; - return true; - } - const QMetaObject *meta = data->value; - if (meta) { - QByteArray name = convertToLatin1(propertyName.ustring()); - for (int i = 0; i < meta->enumeratorCount(); ++i) { - QMetaEnum e = meta->enumerator(i); - for (int j = 0; j < e.keyCount(); ++j) { - if (!qstrcmp(e.key(j), name.constData())) { - attributes = JSC::ReadOnly | JSC::DontDelete; - return true; - } - } - } - } - return JSC::JSObject::getPropertyAttributes(exec, propertyName, attributes); + return JSC::JSObject::deleteProperty(exec, propertyName); } void QMetaObjectWrapperObject::getOwnPropertyNames(JSC::ExecState *exec, JSC::PropertyNameArray &propertyNames, - bool includeNonEnumerable) + JSC::EnumerationMode mode) { const QMetaObject *meta = data->value; if (!meta) @@ -1964,7 +1892,7 @@ void QMetaObjectWrapperObject::getOwnPropertyNames(JSC::ExecState *exec, for (int j = 0; j < e.keyCount(); ++j) propertyNames.add(JSC::Identifier(exec, e.key(j))); } - JSC::JSObject::getOwnPropertyNames(exec, propertyNames, includeNonEnumerable); + JSC::JSObject::getOwnPropertyNames(exec, propertyNames, mode); } void QMetaObjectWrapperObject::markChildren(JSC::MarkStack& markStack) diff --git a/src/script/bridge/qscriptqobject_p.h b/src/script/bridge/qscriptqobject_p.h index 8b05d6b..b82bcb7 100644 --- a/src/script/bridge/qscriptqobject_p.h +++ b/src/script/bridge/qscriptqobject_p.h @@ -86,14 +86,10 @@ public: const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&); virtual bool deleteProperty(QScriptObject*, JSC::ExecState*, - const JSC::Identifier& propertyName, - bool checkDontDelete = true); - virtual bool getPropertyAttributes(const QScriptObject*, JSC::ExecState*, - const JSC::Identifier&, - unsigned&) const; + const JSC::Identifier& propertyName); virtual void getOwnPropertyNames(QScriptObject*, JSC::ExecState*, JSC::PropertyNameArray&, - bool includeNonEnumerable = false); + JSC::EnumerationMode mode = JSC::ExcludeDontEnumProperties); virtual void markChildren(QScriptObject*, JSC::MarkStack& markStack); virtual bool compareToObject(QScriptObject*, JSC::ExecState*, JSC::JSObject*); @@ -275,15 +271,15 @@ public: virtual bool getOwnPropertySlot(JSC::ExecState*, const JSC::Identifier& propertyName, JSC::PropertySlot&); + virtual bool getOwnPropertyDescriptor(JSC::ExecState*, + const JSC::Identifier& propertyName, + JSC::PropertyDescriptor&); virtual void put(JSC::ExecState* exec, const JSC::Identifier& propertyName, JSC::JSValue, JSC::PutPropertySlot&); virtual bool deleteProperty(JSC::ExecState*, - const JSC::Identifier& propertyName, - bool checkDontDelete = true); - virtual bool getPropertyAttributes(JSC::ExecState*, const JSC::Identifier&, - unsigned&) const; + const JSC::Identifier& propertyName); virtual void getOwnPropertyNames(JSC::ExecState*, JSC::PropertyNameArray&, - bool includeNonEnumerable = false); + JSC::EnumerationMode mode = JSC::ExcludeDontEnumProperties); virtual void markChildren(JSC::MarkStack& markStack); virtual JSC::CallType getCallData(JSC::CallData&); @@ -303,10 +299,12 @@ public: static WTF::PassRefPtr<JSC::Structure> createStructure(JSC::JSValue prototype) { - return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType)); + return JSC::Structure::create(prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags)); } protected: + static const unsigned StructureFlags = JSC::OverridesGetOwnPropertySlot | JSC::OverridesMarkChildren | JSC::OverridesGetPropertyNames | JSObject::StructureFlags; + Data *data; }; diff --git a/src/script/bridge/qscriptvariant.cpp b/src/script/bridge/qscriptvariant.cpp index b4f0365..b2dd3b0 100644 --- a/src/script/bridge/qscriptvariant.cpp +++ b/src/script/bridge/qscriptvariant.cpp @@ -119,11 +119,8 @@ static JSC::JSValue JSC_HOST_CALL variantProtoFuncToString(JSC::ExecState *exec, JSC::JSValue value = variantProtoFuncValueOf(exec, callee, thisValue, args); if (value.isObject()) { result = v.toString(); - if (result.isEmpty() && !v.canConvert(QVariant::String)) { - result = "QVariant("; - result += v.typeName(); - result += ")"; - } + if (result.isEmpty() && !v.canConvert(QVariant::String)) + result = QString::fromLatin1("QVariant(%0)").arg(QString::fromLatin1(v.typeName())); } else { result = value.toString(exec); } |