Changeset 63318 in webkit
- Timestamp:
- Jul 14, 2010 7:35:08 AM (14 years ago)
- Location:
- trunk/JavaScriptCore/qt
- Files:
-
- 1 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/qt/ChangeLog
r63233 r63318 1 2010-07-14 Jedrzej Nowacki <jedrzej.nowacki@nokia.com> 2 3 Reviewed by Kenneth Rohde Christiansen. 4 5 Introduce QScriptOriginalGlobalObject. 6 7 QtScript exposes more functionality than JSC C API. Sometimes it is 8 necessary to take a shortcut in implementation. Really often we have 9 to use a standard JS function. These function could be changed or 10 even deleted by a script, so a backup of a reference to an object is needed. 11 12 In them same time this is rather a workaround then real fix, so the code 13 should be separated and changed easily in future. It is why we need 14 the new internal class. 15 16 The patch fixes a few crashes. 17 18 [Qt] QScriptEngine should work correctly even after global object changes 19 https://bugs.webkit.org/show_bug.cgi?id=41839 20 21 * api/QtScript.pro: 22 * api/qscriptengine_p.cpp: 23 (QScriptEnginePrivate::QScriptEnginePrivate): 24 (QScriptEnginePrivate::~QScriptEnginePrivate): 25 * api/qscriptengine_p.h: 26 (QScriptEnginePrivate::isArray): 27 (QScriptEnginePrivate::isError): 28 (QScriptEnginePrivate::objectHasOwnProperty): 29 (QScriptEnginePrivate::objectGetOwnPropertyNames): 30 * api/qscriptoriginalglobalobject_p.h: Added. 31 (QScriptOriginalGlobalObject::QScriptOriginalGlobalObject): 32 (QScriptOriginalGlobalObject::initializeMember): 33 (QScriptOriginalGlobalObject::~QScriptOriginalGlobalObject): 34 (QScriptOriginalGlobalObject::objectHasOwnProperty): 35 (QScriptOriginalGlobalObject::objectGetOwnPropertyNames): 36 (QScriptOriginalGlobalObject::isArray): 37 (QScriptOriginalGlobalObject::isError): 38 (QScriptOriginalGlobalObject::isType): 39 * api/qscriptvalue_p.h: 40 (QScriptValuePrivate::isError): 41 (QScriptValuePrivate::hasOwnProperty): 42 * api/qscriptvalueiterator_p.h: 43 (QScriptValueIteratorPrivate::QScriptValueIteratorPrivate): 44 * tests/qscriptvalue/tst_qscriptvalue.cpp: 45 (tst_QScriptValue::globalObjectChanges): 46 * tests/qscriptvalue/tst_qscriptvalue.h: 47 1 48 2010-07-13 Jedrzej Nowacki <jedrzej.nowacki@nokia.com> 2 49 -
trunk/JavaScriptCore/qt/api/QtScript.pro
r63233 r63318 43 43 $$PWD/qscriptprogram_p.h \ 44 44 $$PWD/qscriptsyntaxcheckresult.h \ 45 $$PWD/qscriptoriginalglobalobject_p.h \ 45 46 46 47 -
trunk/JavaScriptCore/qt/api/qscriptengine_p.cpp
r62661 r63318 33 33 , m_context(JSGlobalContextCreate(0)) 34 34 , m_exception(0) 35 , m_arrayConstructor(0) 36 , m_arrayPrototype(0) 35 , m_originalGlobalObject(m_context) 37 36 { 38 JSObjectRef globalObject = JSContextGetGlobalObject(m_context);39 40 // Save references to the Array constructor and prototype.41 JSRetainPtr<JSStringRef> arrayName(Adopt, JSStringCreateWithUTF8CString("Array"));42 JSValueRef arrayConstructor = JSObjectGetProperty(m_context, globalObject, arrayName.get(), /* exception */ 0);43 Q_ASSERT(JSValueIsObject(m_context, arrayConstructor));44 m_arrayConstructor = JSValueToObject(m_context, arrayConstructor, /* exception */ 0);45 JSValueProtect(m_context, m_arrayConstructor);46 47 // Note that this is not the [[Prototype]] internal property (which we could48 // get via JSObjectGetPrototype), but the Array.prototype, that will be set49 // as [[Prototype]] of Array instances.50 JSRetainPtr<JSStringRef> prototypeName(Adopt, JSStringCreateWithUTF8CString("prototype"));51 JSValueRef arrayPrototype = JSObjectGetProperty(m_context, m_arrayConstructor, prototypeName.get(), /* exception */ 0);52 Q_ASSERT(JSValueIsObject(m_context, arrayPrototype));53 m_arrayPrototype = arrayPrototype;54 JSValueProtect(m_context, m_arrayPrototype);55 37 } 56 38 57 39 QScriptEnginePrivate::~QScriptEnginePrivate() 58 40 { 59 JSValueUnprotect(m_context, m_arrayConstructor);60 JSValueUnprotect(m_context, m_arrayPrototype);61 41 if (m_exception) 62 42 JSValueUnprotect(m_context, m_exception); -
trunk/JavaScriptCore/qt/api/qscriptengine_p.h
r62661 r63318 23 23 #include "qscriptconverter_p.h" 24 24 #include "qscriptengine.h" 25 #include "qscriptoriginalglobalobject_p.h" 25 26 #include "qscriptstring_p.h" 26 27 #include "qscriptsyntaxcheckresult_p.h" … … 80 81 81 82 inline bool isArray(JSValueRef value) const; 83 inline bool isError(JSValueRef value) const; 84 inline bool objectHasOwnProperty(JSObjectRef object, JSStringRef property) const; 85 inline QVector<JSStringRef> objectGetOwnPropertyNames(JSObjectRef object) const; 82 86 private: 83 87 QScriptEngine* q_ptr; … … 85 89 JSValueRef m_exception; 86 90 87 JSObjectRef m_arrayConstructor; 88 JSValueRef m_arrayPrototype; 91 QScriptOriginalGlobalObject m_originalGlobalObject; 89 92 }; 90 93 … … 219 222 bool QScriptEnginePrivate::isArray(JSValueRef value) const 220 223 { 221 // JSC API doesn't export the [[Class]] information for the builtins. But we know that a value 222 // is an array if it was created with the Array constructor or if it is the Array.prototype. 223 return JSValueIsInstanceOfConstructor(m_context, value, m_arrayConstructor, /* exception */ 0) || JSValueIsStrictEqual(m_context, value, m_arrayPrototype); 224 return m_originalGlobalObject.isArray(value); 225 } 226 227 bool QScriptEnginePrivate::isError(JSValueRef value) const 228 { 229 return m_originalGlobalObject.isError(value); 230 } 231 232 inline bool QScriptEnginePrivate::objectHasOwnProperty(JSObjectRef object, JSStringRef property) const 233 { 234 // FIXME We need a JSC C API function for this. 235 return m_originalGlobalObject.objectHasOwnProperty(object, property); 236 } 237 238 inline QVector<JSStringRef> QScriptEnginePrivate::objectGetOwnPropertyNames(JSObjectRef object) const 239 { 240 // FIXME We can't use C API function JSObjectGetPropertyNames as it returns only enumerable properties. 241 return m_originalGlobalObject.objectGetOwnPropertyNames(object); 224 242 } 225 243 -
trunk/JavaScriptCore/qt/api/qscriptvalue_p.h
r62921 r63318 185 185 } u; 186 186 187 inline bool inherits(const char*);188 187 inline State refinedJSValue(); 189 188 … … 417 416 // Fall-through. 418 417 case JSObject: 419 return inherits("Error");418 return m_engine->isError(*this); 420 419 default: 421 420 return false; … … 869 868 { 870 869 Q_ASSERT(isObject()); 871 // FIXME it could be faster, but JSC C API doesn't expose needed functionality. 872 JSRetainPtr<JSStringRef> hasOwnPropertyName(Adopt, JSStringCreateWithUTF8CString("hasOwnProperty")); 873 JSValueRef exception = 0; 874 JSValueRef hasOwnProperty = JSObjectGetProperty(*m_engine, *this, hasOwnPropertyName.get(), &exception); 875 JSValueRef propertyName[] = { JSValueMakeString(*m_engine, property) }; 876 JSValueRef result = JSObjectCallAsFunction(*m_engine, const_cast<JSObjectRef>(hasOwnProperty), *this, 1, propertyName, &exception); 877 return exception ? false : JSValueToBoolean(*m_engine, result); 870 return m_engine->objectHasOwnProperty(*this, property); 878 871 } 879 872 … … 1125 1118 /*! 1126 1119 \internal 1127 Returns true if QSV is created from constructor with the given \a name, it has to be a1128 built-in type.1129 */1130 bool QScriptValuePrivate::inherits(const char* name)1131 {1132 Q_ASSERT(isJSBased());1133 JSObjectRef globalObject = JSContextGetGlobalObject(*m_engine);1134 JSStringRef errorAttrName = QScriptConverter::toString(name);1135 JSValueRef exception = 0;1136 JSValueRef error = JSObjectGetProperty(*m_engine, globalObject, errorAttrName, &exception);1137 JSStringRelease(errorAttrName);1138 bool result = JSValueIsInstanceOfConstructor(*m_engine, *this, JSValueToObject(*m_engine, error, &exception), &exception);1139 m_engine->setException(exception);1140 return result;1141 }1142 1143 /*!1144 \internal1145 1120 Refines the state of this QScriptValuePrivate. Returns the new state. 1146 1121 */ -
trunk/JavaScriptCore/qt/api/qscriptvalueiterator_p.h
r63233 r63318 64 64 , m_idx(m_names) 65 65 { 66 // FIXME There is assumption that global object wasn't changed (bug 41839). 67 // FIXME We can't use C API function JSObjectGetPropertyNames as it returns only enumerable properties. 68 if (const_cast<QScriptValuePrivate*>(value)->isObject()) { 69 static JSStringRef objectName = QScriptConverter::toString("Object"); 70 static JSStringRef getOwnPropertyNamesName = QScriptConverter::toString("getOwnPropertyNames"); 71 72 JSValueRef exception = 0; 73 JSObjectRef globalObject = JSContextGetGlobalObject(*engine()); 74 Q_ASSERT(JSValueIsObject(*engine(), globalObject)); 75 JSValueRef objectConstructor = JSObjectGetProperty(*engine(), globalObject, objectName, &exception); 76 Q_ASSERT(JSValueIsObject(*engine(), objectConstructor)); 77 Q_ASSERT(!exception); 78 JSValueRef propertyNamesGetter = JSObjectGetProperty(*engine(), const_cast<JSObjectRef>(objectConstructor), getOwnPropertyNamesName, &exception); 79 Q_ASSERT(JSValueIsObject(*engine(), propertyNamesGetter)); 80 Q_ASSERT(!exception); 81 82 JSValueRef arguments[] = { *m_object }; 83 JSObjectRef propertyNames 84 = const_cast<JSObjectRef>(JSObjectCallAsFunction(*engine(), 85 const_cast<JSObjectRef>(propertyNamesGetter), 86 /* thisObject */ 0, 87 /* argumentCount */ 1, 88 arguments, 89 &exception)); 90 Q_ASSERT(JSValueIsObject(*engine(), propertyNames)); 91 Q_ASSERT(!exception); 92 static JSStringRef lengthName = QScriptConverter::toString("length"); 93 int count = JSValueToNumber(*engine(), JSObjectGetProperty(*engine(), propertyNames, lengthName, &exception), &exception); 94 95 Q_ASSERT(!exception); 96 m_names.reserve(count); 97 for (int i = 0; i < count; ++i) { 98 JSValueRef tmp = JSObjectGetPropertyAtIndex(*engine(), propertyNames, i, &exception); 99 m_names.append(JSValueToStringCopy(*engine(), tmp, &exception)); 100 Q_ASSERT(!exception); 101 } 66 if (m_object->isObject()) { 67 m_names = engine()->objectGetOwnPropertyNames(*m_object); 102 68 m_idx = m_names; 103 69 } else -
trunk/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.cpp
r62921 r63318 1262 1262 } 1263 1263 1264 void tst_QScriptValue::globalObjectChanges() 1265 { 1266 // API functionality shouldn't depend on Global Object. 1267 QScriptEngine engine; 1268 QScriptValue array = engine.newArray(); 1269 QScriptValue error = engine.evaluate("new Error"); 1270 QScriptValue object = engine.newObject(); 1271 1272 object.setProperty("foo", 512); 1273 1274 // Remove properties form global object. 1275 engine.evaluate("delete Object; delete Error; delete Array;"); 1276 1277 QVERIFY(array.isArray()); 1278 QVERIFY(error.isError()); 1279 QVERIFY(object.isObject()); 1280 1281 QVERIFY(object.property("foo").isValid()); 1282 QVERIFY(object.property("foo", QScriptValue::ResolveLocal).isValid()); 1283 object.setProperty("foo", QScriptValue()); 1284 QVERIFY(!object.property("foo").isValid()); 1285 QVERIFY(!object.property("foo", QScriptValue::ResolveLocal).isValid()); 1286 } 1287 1264 1288 QTEST_MAIN(tst_QScriptValue) -
trunk/JavaScriptCore/qt/tests/qscriptvalue/tst_qscriptvalue.h
r62921 r63318 61 61 void propertyFlag_data(); 62 62 void propertyFlag(); 63 void globalObjectChanges(); 63 64 64 65 // Generated test functions.
Note: See TracChangeset
for help on using the changeset viewer.