branch | GCC_SURGE |
changeset 31 | 5daf16870df6 |
parent 30 | 5dc02b23752f |
child 33 | 3e2da88830cd |
27:93b982ccede2 | 31:5daf16870df6 |
---|---|
27 #include "qscriptvalue_p.h" |
27 #include "qscriptvalue_p.h" |
28 #include "qscriptengine.h" |
28 #include "qscriptengine.h" |
29 #include "qscriptengine_p.h" |
29 #include "qscriptengine_p.h" |
30 #include "qscriptstring_p.h" |
30 #include "qscriptstring_p.h" |
31 |
31 |
32 #include "JSArray.h" |
|
33 #include "JSGlobalObject.h" |
32 #include "JSGlobalObject.h" |
34 #include "JSImmediate.h" |
33 #include "JSImmediate.h" |
35 #include "JSObject.h" |
34 #include "JSObject.h" |
36 #include "JSValue.h" |
35 #include "JSValue.h" |
37 #include "JSFunction.h" |
36 #include "JSFunction.h" |
38 #include "DateInstance.h" |
|
39 #include "ErrorInstance.h" |
|
40 #include "RegExpObject.h" |
|
41 #include "Identifier.h" |
37 #include "Identifier.h" |
42 #include "Operations.h" |
38 #include "Operations.h" |
43 #include "Arguments.h" |
39 #include "Arguments.h" |
44 |
40 |
45 #include <QtCore/qdatetime.h> |
|
46 #include <QtCore/qregexp.h> |
|
47 #include <QtCore/qvariant.h> |
41 #include <QtCore/qvariant.h> |
48 #include <QtCore/qvarlengtharray.h> |
42 #include <QtCore/qvarlengtharray.h> |
49 #include <QtCore/qnumeric.h> |
43 #include <QtCore/qnumeric.h> |
50 |
|
51 #include "utils/qscriptdate_p.h" |
|
52 #include "bridge/qscriptobject_p.h" |
|
53 #include "bridge/qscriptclassobject_p.h" |
|
54 #include "bridge/qscriptvariant_p.h" |
|
55 #include "bridge/qscriptqobject_p.h" |
|
56 #include "bridge/qscriptdeclarativeclass_p.h" |
|
57 #include "bridge/qscriptdeclarativeobject_p.h" |
|
58 |
44 |
59 /*! |
45 /*! |
60 \since 4.3 |
46 \since 4.3 |
61 \class QScriptValue |
47 \class QScriptValue |
62 |
48 |
178 \omitvalue ResolveScope Check the object's own properties first, then search the scope chain. |
164 \omitvalue ResolveScope Check the object's own properties first, then search the scope chain. |
179 |
165 |
180 \omitvalue ResolveFull Check the object's own properties first, then search the prototype chain, and finally search the scope chain. |
166 \omitvalue ResolveFull Check the object's own properties first, then search the prototype chain, and finally search the scope chain. |
181 */ |
167 */ |
182 |
168 |
183 // ### move |
|
184 |
|
185 #include <QtCore/qnumeric.h> |
|
186 #include <math.h> |
|
187 |
|
188 QT_BEGIN_NAMESPACE |
169 QT_BEGIN_NAMESPACE |
189 |
|
190 namespace QScript |
|
191 { |
|
192 |
|
193 static const qsreal D32 = 4294967296.0; |
|
194 |
|
195 qint32 ToInt32(qsreal n) |
|
196 { |
|
197 if (qIsNaN(n) || qIsInf(n) || (n == 0)) |
|
198 return 0; |
|
199 |
|
200 qsreal sign = (n < 0) ? -1.0 : 1.0; |
|
201 qsreal abs_n = fabs(n); |
|
202 |
|
203 n = ::fmod(sign * ::floor(abs_n), D32); |
|
204 const double D31 = D32 / 2.0; |
|
205 |
|
206 if (sign == -1 && n < -D31) |
|
207 n += D32; |
|
208 |
|
209 else if (sign != -1 && n >= D31) |
|
210 n -= D32; |
|
211 |
|
212 return qint32 (n); |
|
213 } |
|
214 |
|
215 quint32 ToUint32(qsreal n) |
|
216 { |
|
217 if (qIsNaN(n) || qIsInf(n) || (n == 0)) |
|
218 return 0; |
|
219 |
|
220 qsreal sign = (n < 0) ? -1.0 : 1.0; |
|
221 qsreal abs_n = fabs(n); |
|
222 |
|
223 n = ::fmod(sign * ::floor(abs_n), D32); |
|
224 |
|
225 if (n < 0) |
|
226 n += D32; |
|
227 |
|
228 return quint32 (n); |
|
229 } |
|
230 |
|
231 quint16 ToUint16(qsreal n) |
|
232 { |
|
233 static const qsreal D16 = 65536.0; |
|
234 |
|
235 if (qIsNaN(n) || qIsInf(n) || (n == 0)) |
|
236 return 0; |
|
237 |
|
238 qsreal sign = (n < 0) ? -1.0 : 1.0; |
|
239 qsreal abs_n = fabs(n); |
|
240 |
|
241 n = ::fmod(sign * ::floor(abs_n), D16); |
|
242 |
|
243 if (n < 0) |
|
244 n += D16; |
|
245 |
|
246 return quint16 (n); |
|
247 } |
|
248 |
|
249 qsreal ToInteger(qsreal n) |
|
250 { |
|
251 if (qIsNaN(n)) |
|
252 return 0; |
|
253 |
|
254 if (n == 0 || qIsInf(n)) |
|
255 return n; |
|
256 |
|
257 int sign = n < 0 ? -1 : 1; |
|
258 return sign * ::floor(::fabs(n)); |
|
259 } |
|
260 |
|
261 } // namespace QScript |
|
262 |
|
263 QScriptValue QScriptValuePrivate::propertyHelper(const JSC::Identifier &id, int resolveMode) const |
|
264 { |
|
265 JSC::JSValue result; |
|
266 if (!(resolveMode & QScriptValue::ResolvePrototype)) { |
|
267 // Look in the object's own properties |
|
268 JSC::ExecState *exec = engine->currentFrame; |
|
269 JSC::JSObject *object = JSC::asObject(jscValue); |
|
270 JSC::PropertySlot slot(object); |
|
271 if (object->getOwnPropertySlot(exec, id, slot)) |
|
272 result = slot.getValue(exec, id); |
|
273 } |
|
274 if (!result && (resolveMode & QScriptValue::ResolveScope)) { |
|
275 // ### check if it's a function object and look in the scope chain |
|
276 QScriptValue scope = property(QString::fromLatin1("__qt_scope__"), QScriptValue::ResolveLocal); |
|
277 if (scope.isObject()) |
|
278 result = engine->scriptValueToJSCValue(QScriptValuePrivate::get(scope)->property(id, resolveMode)); |
|
279 } |
|
280 return engine->scriptValueFromJSCValue(result); |
|
281 } |
|
282 |
|
283 QScriptValue QScriptValuePrivate::propertyHelper(quint32 index, int resolveMode) const |
|
284 { |
|
285 JSC::JSValue result; |
|
286 if (!(resolveMode & QScriptValue::ResolvePrototype)) { |
|
287 // Look in the object's own properties |
|
288 JSC::ExecState *exec = engine->currentFrame; |
|
289 JSC::JSObject *object = JSC::asObject(jscValue); |
|
290 JSC::PropertySlot slot(object); |
|
291 if (object->getOwnPropertySlot(exec, index, slot)) |
|
292 result = slot.getValue(exec, index); |
|
293 } |
|
294 return engine->scriptValueFromJSCValue(result); |
|
295 } |
|
296 |
|
297 void QScriptValuePrivate::setProperty(const JSC::Identifier &id, const QScriptValue &value, |
|
298 const QScriptValue::PropertyFlags &flags) |
|
299 { |
|
300 QScriptEnginePrivate *valueEngine = QScriptValuePrivate::getEngine(value); |
|
301 if (valueEngine && (valueEngine != engine)) { |
|
302 qWarning("QScriptValue::setProperty(%s) failed: " |
|
303 "cannot set value created in a different engine", |
|
304 qPrintable(QString(id.ustring()))); |
|
305 return; |
|
306 } |
|
307 JSC::ExecState *exec = engine->currentFrame; |
|
308 JSC::JSValue jsValue = engine->scriptValueToJSCValue(value); |
|
309 JSC::JSObject *thisObject = JSC::asObject(jscValue); |
|
310 JSC::JSValue setter = thisObject->lookupSetter(exec, id); |
|
311 JSC::JSValue getter = thisObject->lookupGetter(exec, id); |
|
312 if ((flags & QScriptValue::PropertyGetter) || (flags & QScriptValue::PropertySetter)) { |
|
313 if (!jsValue) { |
|
314 // deleting getter/setter |
|
315 if ((flags & QScriptValue::PropertyGetter) && (flags & QScriptValue::PropertySetter)) { |
|
316 // deleting both: just delete the property |
|
317 thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); |
|
318 } else if (flags & QScriptValue::PropertyGetter) { |
|
319 // preserve setter, if there is one |
|
320 thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); |
|
321 if (setter && setter.isObject()) |
|
322 thisObject->defineSetter(exec, id, JSC::asObject(setter)); |
|
323 } else { // flags & QScriptValue::PropertySetter |
|
324 // preserve getter, if there is one |
|
325 thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); |
|
326 if (getter && getter.isObject()) |
|
327 thisObject->defineGetter(exec, id, JSC::asObject(getter)); |
|
328 } |
|
329 } else { |
|
330 if (jsValue.isObject()) { // ### should check if it has callData() |
|
331 // defining getter/setter |
|
332 if (id == exec->propertyNames().underscoreProto) { |
|
333 qWarning("QScriptValue::setProperty() failed: " |
|
334 "cannot set getter or setter of native property `__proto__'"); |
|
335 } else { |
|
336 if (flags & QScriptValue::PropertyGetter) |
|
337 thisObject->defineGetter(exec, id, JSC::asObject(jsValue)); |
|
338 if (flags & QScriptValue::PropertySetter) |
|
339 thisObject->defineSetter(exec, id, JSC::asObject(jsValue)); |
|
340 } |
|
341 } else { |
|
342 qWarning("QScriptValue::setProperty(): getter/setter must be a function"); |
|
343 } |
|
344 } |
|
345 } else { |
|
346 // setting the value |
|
347 if (getter && getter.isObject() && !(setter && setter.isObject())) { |
|
348 qWarning("QScriptValue::setProperty() failed: " |
|
349 "property '%s' has a getter but no setter", |
|
350 qPrintable(QString(id.ustring()))); |
|
351 return; |
|
352 } |
|
353 if (!jsValue) { |
|
354 // ### check if it's a getter/setter property |
|
355 thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); |
|
356 } else if (flags != QScriptValue::KeepExistingFlags) { |
|
357 if (thisObject->hasOwnProperty(exec, id)) |
|
358 thisObject->deleteProperty(exec, id, /*checkDontDelete=*/false); // ### hmmm - can't we just update the attributes? |
|
359 unsigned attribs = 0; |
|
360 if (flags & QScriptValue::ReadOnly) |
|
361 attribs |= JSC::ReadOnly; |
|
362 if (flags & QScriptValue::SkipInEnumeration) |
|
363 attribs |= JSC::DontEnum; |
|
364 if (flags & QScriptValue::Undeletable) |
|
365 attribs |= JSC::DontDelete; |
|
366 attribs |= flags & QScriptValue::UserRange; |
|
367 thisObject->putWithAttributes(exec, id, jsValue, attribs); |
|
368 } else { |
|
369 JSC::PutPropertySlot slot; |
|
370 thisObject->put(exec, id, jsValue, slot); |
|
371 } |
|
372 } |
|
373 } |
|
374 |
|
375 QScriptValue::PropertyFlags QScriptValuePrivate::propertyFlags(const JSC::Identifier &id, |
|
376 const QScriptValue::ResolveFlags &mode) const |
|
377 { |
|
378 JSC::ExecState *exec = engine->currentFrame; |
|
379 JSC::JSObject *object = JSC::asObject(jscValue); |
|
380 unsigned attribs = 0; |
|
381 JSC::PropertyDescriptor descriptor; |
|
382 if (object->getOwnPropertyDescriptor(exec, id, descriptor)) |
|
383 attribs = descriptor.attributes(); |
|
384 else if (!object->getPropertyAttributes(exec, id, attribs)) { |
|
385 if ((mode & QScriptValue::ResolvePrototype) && object->prototype() && object->prototype().isObject()) { |
|
386 QScriptValue proto = engine->scriptValueFromJSCValue(object->prototype()); |
|
387 return QScriptValuePrivate::get(proto)->propertyFlags(id, mode); |
|
388 } |
|
389 return 0; |
|
390 } |
|
391 QScriptValue::PropertyFlags result = 0; |
|
392 if (attribs & JSC::ReadOnly) |
|
393 result |= QScriptValue::ReadOnly; |
|
394 if (attribs & JSC::DontEnum) |
|
395 result |= QScriptValue::SkipInEnumeration; |
|
396 if (attribs & JSC::DontDelete) |
|
397 result |= QScriptValue::Undeletable; |
|
398 //We cannot rely on attribs JSC::Setter/Getter because they are not necesserly set by JSC (bug?) |
|
399 if (attribs & JSC::Getter || !object->lookupGetter(exec, id).isUndefinedOrNull()) |
|
400 result |= QScriptValue::PropertyGetter; |
|
401 if (attribs & JSC::Setter || !object->lookupSetter(exec, id).isUndefinedOrNull()) |
|
402 result |= QScriptValue::PropertySetter; |
|
403 if (attribs & QScript::QObjectMemberAttribute) |
|
404 result |= QScriptValue::QObjectMember; |
|
405 result |= QScriptValue::PropertyFlag(attribs & QScriptValue::UserRange); |
|
406 return result; |
|
407 } |
|
408 |
|
409 QVariant &QScriptValuePrivate::variantValue() const |
|
410 { |
|
411 Q_ASSERT(jscValue.inherits(&QScriptObject::info)); |
|
412 QScriptObjectDelegate *delegate = static_cast<QScriptObject*>(JSC::asObject(jscValue))->delegate(); |
|
413 Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::Variant)); |
|
414 return static_cast<QScript::QVariantDelegate*>(delegate)->value(); |
|
415 } |
|
416 |
|
417 void QScriptValuePrivate::setVariantValue(const QVariant &value) |
|
418 { |
|
419 Q_ASSERT(jscValue.inherits(&QScriptObject::info)); |
|
420 QScriptObjectDelegate *delegate = static_cast<QScriptObject*>(JSC::asObject(jscValue))->delegate(); |
|
421 Q_ASSERT(delegate && (delegate->type() == QScriptObjectDelegate::Variant)); |
|
422 static_cast<QScript::QVariantDelegate*>(delegate)->setValue(value); |
|
423 } |
|
424 |
170 |
425 void QScriptValuePrivate::detachFromEngine() |
171 void QScriptValuePrivate::detachFromEngine() |
426 { |
172 { |
427 if (isJSC()) |
173 if (isJSC()) |
428 jscValue = JSC::JSValue(); |
174 jscValue = JSC::JSValue(); |
705 \sa QScriptContext::throwError() |
451 \sa QScriptContext::throwError() |
706 */ |
452 */ |
707 bool QScriptValue::isError() const |
453 bool QScriptValue::isError() const |
708 { |
454 { |
709 Q_D(const QScriptValue); |
455 Q_D(const QScriptValue); |
710 if (!d || !d->isObject()) |
456 if (!d || !d->isJSC()) |
711 return false; |
457 return false; |
712 return d->jscValue.inherits(&JSC::ErrorInstance::info); |
458 return QScriptEnginePrivate::isError(d->jscValue); |
713 } |
459 } |
714 |
460 |
715 /*! |
461 /*! |
716 Returns true if this QScriptValue is an object of the Array class; |
462 Returns true if this QScriptValue is an object of the Array class; |
717 otherwise returns false. |
463 otherwise returns false. |
719 \sa QScriptEngine::newArray() |
465 \sa QScriptEngine::newArray() |
720 */ |
466 */ |
721 bool QScriptValue::isArray() const |
467 bool QScriptValue::isArray() const |
722 { |
468 { |
723 Q_D(const QScriptValue); |
469 Q_D(const QScriptValue); |
724 if (!d || !d->isObject()) |
470 if (!d || !d->isJSC()) |
725 return false; |
471 return false; |
726 return d->jscValue.inherits(&JSC::JSArray::info); |
472 return QScriptEnginePrivate::isArray(d->jscValue); |
727 } |
473 } |
728 |
474 |
729 /*! |
475 /*! |
730 Returns true if this QScriptValue is an object of the Date class; |
476 Returns true if this QScriptValue is an object of the Date class; |
731 otherwise returns false. |
477 otherwise returns false. |
733 \sa QScriptEngine::newDate() |
479 \sa QScriptEngine::newDate() |
734 */ |
480 */ |
735 bool QScriptValue::isDate() const |
481 bool QScriptValue::isDate() const |
736 { |
482 { |
737 Q_D(const QScriptValue); |
483 Q_D(const QScriptValue); |
738 if (!d || !d->isObject()) |
484 if (!d || !d->isJSC()) |
739 return false; |
485 return false; |
740 return d->jscValue.inherits(&JSC::DateInstance::info); |
486 return QScriptEnginePrivate::isDate(d->jscValue); |
741 } |
487 } |
742 |
488 |
743 /*! |
489 /*! |
744 Returns true if this QScriptValue is an object of the RegExp class; |
490 Returns true if this QScriptValue is an object of the RegExp class; |
745 otherwise returns false. |
491 otherwise returns false. |
747 \sa QScriptEngine::newRegExp() |
493 \sa QScriptEngine::newRegExp() |
748 */ |
494 */ |
749 bool QScriptValue::isRegExp() const |
495 bool QScriptValue::isRegExp() const |
750 { |
496 { |
751 Q_D(const QScriptValue); |
497 Q_D(const QScriptValue); |
752 if (!d || !d->isObject()) |
498 if (!d || !d->isJSC()) |
753 return false; |
499 return false; |
754 return d->jscValue.inherits(&JSC::RegExpObject::info); |
500 return QScriptEnginePrivate::isRegExp(d->jscValue); |
755 } |
501 } |
756 |
502 |
757 /*! |
503 /*! |
758 If this QScriptValue is an object, returns the internal prototype |
504 If this QScriptValue is an object, returns the internal prototype |
759 (\c{__proto__} property) of this object; otherwise returns an |
505 (\c{__proto__} property) of this object; otherwise returns an |
822 QScriptValue QScriptValue::scope() const |
568 QScriptValue QScriptValue::scope() const |
823 { |
569 { |
824 Q_D(const QScriptValue); |
570 Q_D(const QScriptValue); |
825 if (!d || !d->isObject()) |
571 if (!d || !d->isObject()) |
826 return QScriptValue(); |
572 return QScriptValue(); |
573 QScript::APIShim shim(d->engine); |
|
827 // ### make hidden property |
574 // ### make hidden property |
828 return d->property(QLatin1String("__qt_scope__"), QScriptValue::ResolveLocal); |
575 JSC::JSValue result = d->property("__qt_scope__", QScriptValue::ResolveLocal); |
576 return d->engine->scriptValueFromJSCValue(result); |
|
829 } |
577 } |
830 |
578 |
831 /*! |
579 /*! |
832 \internal |
580 \internal |
833 */ |
581 */ |
910 return Number; |
658 return Number; |
911 Q_ASSERT(v.isObject()); |
659 Q_ASSERT(v.isObject()); |
912 return Object; |
660 return Object; |
913 } |
661 } |
914 |
662 |
915 QScriptValue ToPrimitive(const QScriptValue &object, JSC::PreferredPrimitiveType hint = JSC::NoPreference) |
663 static QScriptValue ToPrimitive(const QScriptValue &object, JSC::PreferredPrimitiveType hint = JSC::NoPreference) |
916 { |
664 { |
917 Q_ASSERT(object.isObject()); |
665 Q_ASSERT(object.isObject()); |
918 QScriptValuePrivate *pp = QScriptValuePrivate::get(object); |
666 QScriptValuePrivate *pp = QScriptValuePrivate::get(object); |
919 Q_ASSERT(pp->engine != 0); |
667 Q_ASSERT(pp->engine != 0); |
668 QScript::APIShim shim(pp->engine); |
|
920 JSC::ExecState *exec = pp->engine->currentFrame; |
669 JSC::ExecState *exec = pp->engine->currentFrame; |
921 JSC::JSValue savedException; |
670 JSC::JSValue savedException; |
922 QScriptValuePrivate::saveException(exec, &savedException); |
671 QScriptEnginePrivate::saveException(exec, &savedException); |
923 JSC::JSValue result = JSC::asObject(pp->jscValue)->toPrimitive(exec, hint); |
672 JSC::JSValue result = JSC::asObject(pp->jscValue)->toPrimitive(exec, hint); |
924 QScriptValuePrivate::restoreException(exec, savedException); |
673 QScriptEnginePrivate::restoreException(exec, savedException); |
925 return pp->engine->scriptValueFromJSCValue(result); |
674 return pp->engine->scriptValueFromJSCValue(result); |
926 } |
675 } |
927 |
676 |
928 static bool IsNumerical(const QScriptValue &value) |
677 static bool IsNumerical(const QScriptValue &value) |
929 { |
678 { |
1108 if (d->isJSC() && other.d_ptr->isJSC()) { |
857 if (d->isJSC() && other.d_ptr->isJSC()) { |
1109 QScriptEnginePrivate *eng_p = d->engine; |
858 QScriptEnginePrivate *eng_p = d->engine; |
1110 if (!eng_p) |
859 if (!eng_p) |
1111 eng_p = other.d_ptr->engine; |
860 eng_p = other.d_ptr->engine; |
1112 if (eng_p) { |
861 if (eng_p) { |
862 QScript::APIShim shim(eng_p); |
|
1113 JSC::ExecState *exec = eng_p->currentFrame; |
863 JSC::ExecState *exec = eng_p->currentFrame; |
1114 JSC::JSValue savedException; |
864 JSC::JSValue savedException; |
1115 QScriptValuePrivate::saveException(exec, &savedException); |
865 QScriptEnginePrivate::saveException(exec, &savedException); |
1116 bool result = JSC::JSValue::equal(exec, d->jscValue, other.d_ptr->jscValue); |
866 bool result = JSC::JSValue::equal(exec, d->jscValue, other.d_ptr->jscValue); |
1117 QScriptValuePrivate::restoreException(exec, savedException); |
867 QScriptEnginePrivate::restoreException(exec, savedException); |
1118 return result; |
868 return result; |
1119 } |
869 } |
1120 } |
870 } |
1121 return QScript::Equals(*this, other); |
871 return QScript::Equals(*this, other); |
1122 } |
872 } |
1158 |
908 |
1159 if (d->type != other.d_ptr->type) { |
909 if (d->type != other.d_ptr->type) { |
1160 if (d->type == QScriptValuePrivate::JavaScriptCore) { |
910 if (d->type == QScriptValuePrivate::JavaScriptCore) { |
1161 QScriptEnginePrivate *eng_p = d->engine ? d->engine : other.d_ptr->engine; |
911 QScriptEnginePrivate *eng_p = d->engine ? d->engine : other.d_ptr->engine; |
1162 if (eng_p) |
912 if (eng_p) |
1163 return JSC::JSValue::strictEqual(d->jscValue, eng_p->scriptValueToJSCValue(other)); |
913 return JSC::JSValue::strictEqual(eng_p->currentFrame, d->jscValue, eng_p->scriptValueToJSCValue(other)); |
1164 } else if (other.d_ptr->type == QScriptValuePrivate::JavaScriptCore) { |
914 } else if (other.d_ptr->type == QScriptValuePrivate::JavaScriptCore) { |
1165 QScriptEnginePrivate *eng_p = other.d_ptr->engine ? other.d_ptr->engine : d->engine; |
915 QScriptEnginePrivate *eng_p = other.d_ptr->engine ? other.d_ptr->engine : d->engine; |
1166 if (eng_p) |
916 if (eng_p) |
1167 return JSC::JSValue::strictEqual(eng_p->scriptValueToJSCValue(*this), other.d_ptr->jscValue); |
917 return JSC::JSValue::strictEqual(eng_p->currentFrame, eng_p->scriptValueToJSCValue(*this), other.d_ptr->jscValue); |
1168 } |
918 } |
1169 |
919 |
1170 return false; |
920 return false; |
1171 } |
921 } |
1172 switch (d->type) { |
922 switch (d->type) { |
1173 case QScriptValuePrivate::JavaScriptCore: |
923 case QScriptValuePrivate::JavaScriptCore: { |
1174 return JSC::JSValue::strictEqual(d->jscValue, other.d_ptr->jscValue); |
924 QScriptEnginePrivate *eng_p = d->engine ? d->engine : other.d_ptr->engine; |
925 JSC::ExecState *exec = eng_p ? eng_p->currentFrame : 0; |
|
926 return JSC::JSValue::strictEqual(exec, d->jscValue, other.d_ptr->jscValue); |
|
927 } |
|
1175 case QScriptValuePrivate::Number: |
928 case QScriptValuePrivate::Number: |
1176 return (d->numberValue == other.d_ptr->numberValue); |
929 return (d->numberValue == other.d_ptr->numberValue); |
1177 case QScriptValuePrivate::String: |
930 case QScriptValuePrivate::String: |
1178 return (d->stringValue == other.d_ptr->stringValue); |
931 return (d->stringValue == other.d_ptr->stringValue); |
1179 } |
932 } |
1197 Q_D(const QScriptValue); |
950 Q_D(const QScriptValue); |
1198 if (!d) |
951 if (!d) |
1199 return QString(); |
952 return QString(); |
1200 switch (d->type) { |
953 switch (d->type) { |
1201 case QScriptValuePrivate::JavaScriptCore: { |
954 case QScriptValuePrivate::JavaScriptCore: { |
1202 JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; |
955 if (d->engine) { |
1203 JSC::JSValue savedException; |
956 QScript::APIShim shim(d->engine); |
1204 QScriptValuePrivate::saveException(exec, &savedException); |
957 return QScriptEnginePrivate::toString(d->engine->currentFrame, d->jscValue); |
1205 JSC::UString str = d->jscValue.toString(exec); |
958 } else { |
1206 if (exec && exec->hadException() && !str.size()) { |
959 return QScriptEnginePrivate::toString(0, d->jscValue); |
1207 JSC::JSValue savedException2; |
960 } } |
1208 QScriptValuePrivate::saveException(exec, &savedException2); |
|
1209 str = savedException2.toString(exec); |
|
1210 QScriptValuePrivate::restoreException(exec, savedException2); |
|
1211 } |
|
1212 if (savedException) |
|
1213 QScriptValuePrivate::restoreException(exec, savedException); |
|
1214 return str; |
|
1215 } |
|
1216 case QScriptValuePrivate::Number: |
961 case QScriptValuePrivate::Number: |
1217 return JSC::UString::from(d->numberValue); |
962 return QScript::ToString(d->numberValue); |
1218 case QScriptValuePrivate::String: |
963 case QScriptValuePrivate::String: |
1219 return d->stringValue; |
964 return d->stringValue; |
1220 } |
965 } |
1221 return QString(); |
966 return QString(); |
1222 } |
967 } |
1238 Q_D(const QScriptValue); |
983 Q_D(const QScriptValue); |
1239 if (!d) |
984 if (!d) |
1240 return 0; |
985 return 0; |
1241 switch (d->type) { |
986 switch (d->type) { |
1242 case QScriptValuePrivate::JavaScriptCore: { |
987 case QScriptValuePrivate::JavaScriptCore: { |
1243 JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; |
988 if (d->engine) { |
1244 JSC::JSValue savedException; |
989 QScript::APIShim shim(d->engine); |
1245 QScriptValuePrivate::saveException(exec, &savedException); |
990 return QScriptEnginePrivate::toNumber(d->engine->currentFrame, d->jscValue); |
1246 qsreal result = d->jscValue.toNumber(exec); |
991 } else { |
1247 QScriptValuePrivate::restoreException(exec, savedException); |
992 return QScriptEnginePrivate::toNumber(0, d->jscValue); |
1248 return result; |
993 } |
1249 } |
994 } |
1250 case QScriptValuePrivate::Number: |
995 case QScriptValuePrivate::Number: |
1251 return d->numberValue; |
996 return d->numberValue; |
1252 case QScriptValuePrivate::String: |
997 case QScriptValuePrivate::String: |
1253 return ((JSC::UString)d->stringValue).toDouble(); |
998 return QScript::ToNumber(d->stringValue); |
1254 } |
999 } |
1255 return 0; |
1000 return 0; |
1256 } |
1001 } |
1257 |
1002 |
1258 /*! |
1003 /*! |
1265 Q_D(const QScriptValue); |
1010 Q_D(const QScriptValue); |
1266 if (!d) |
1011 if (!d) |
1267 return false; |
1012 return false; |
1268 switch (d->type) { |
1013 switch (d->type) { |
1269 case QScriptValuePrivate::JavaScriptCore: { |
1014 case QScriptValuePrivate::JavaScriptCore: { |
1270 JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; |
1015 if (d->engine) { |
1271 JSC::JSValue savedException; |
1016 QScript::APIShim shim(d->engine); |
1272 QScriptValuePrivate::saveException(exec, &savedException); |
1017 return QScriptEnginePrivate::toBool(d->engine->currentFrame, d->jscValue); |
1273 bool result = d->jscValue.toBoolean(exec); |
1018 } else { |
1274 QScriptValuePrivate::restoreException(exec, savedException); |
1019 return QScriptEnginePrivate::toBool(0, d->jscValue); |
1275 return result; |
1020 } |
1276 } |
1021 } |
1277 case QScriptValuePrivate::Number: |
1022 case QScriptValuePrivate::Number: |
1278 return (d->numberValue != 0) && !qIsNaN(d->numberValue); |
1023 return QScript::ToBool(d->numberValue); |
1279 case QScriptValuePrivate::String: |
1024 case QScriptValuePrivate::String: |
1280 return (!d->stringValue.isEmpty()); |
1025 return QScript::ToBool(d->stringValue); |
1281 } |
1026 } |
1282 return false; |
1027 return false; |
1283 } |
1028 } |
1284 |
1029 |
1285 /*! |
1030 /*! |
1301 Q_D(const QScriptValue); |
1046 Q_D(const QScriptValue); |
1302 if (!d) |
1047 if (!d) |
1303 return false; |
1048 return false; |
1304 switch (d->type) { |
1049 switch (d->type) { |
1305 case QScriptValuePrivate::JavaScriptCore: { |
1050 case QScriptValuePrivate::JavaScriptCore: { |
1306 JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; |
1051 if (d->engine) { |
1307 JSC::JSValue savedException; |
1052 QScript::APIShim shim(d->engine); |
1308 QScriptValuePrivate::saveException(exec, &savedException); |
1053 return QScriptEnginePrivate::toBool(d->engine->currentFrame, d->jscValue); |
1309 bool result = d->jscValue.toBoolean(exec); |
1054 } else { |
1310 QScriptValuePrivate::restoreException(exec, savedException); |
1055 return QScriptEnginePrivate::toBool(0, d->jscValue); |
1311 return result; |
1056 } |
1312 } |
1057 } |
1313 case QScriptValuePrivate::Number: |
1058 case QScriptValuePrivate::Number: |
1314 return (d->numberValue != 0) && !qIsNaN(d->numberValue); |
1059 return QScript::ToBool(d->numberValue); |
1315 case QScriptValuePrivate::String: |
1060 case QScriptValuePrivate::String: |
1316 return (!d->stringValue.isEmpty()); |
1061 return QScript::ToBool(d->stringValue); |
1317 } |
1062 } |
1318 return false; |
1063 return false; |
1319 } |
1064 } |
1320 |
1065 |
1321 /*! |
1066 /*! |
1335 Q_D(const QScriptValue); |
1080 Q_D(const QScriptValue); |
1336 if (!d) |
1081 if (!d) |
1337 return 0; |
1082 return 0; |
1338 switch (d->type) { |
1083 switch (d->type) { |
1339 case QScriptValuePrivate::JavaScriptCore: { |
1084 case QScriptValuePrivate::JavaScriptCore: { |
1340 JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; |
1085 if (d->engine) { |
1341 JSC::JSValue savedException; |
1086 QScript::APIShim shim(d->engine); |
1342 QScriptValuePrivate::saveException(exec, &savedException); |
1087 return QScriptEnginePrivate::toInt32(d->engine->currentFrame, d->jscValue); |
1343 qint32 result = d->jscValue.toInt32(exec); |
1088 } else { |
1344 QScriptValuePrivate::restoreException(exec, savedException); |
1089 return QScriptEnginePrivate::toInt32(0, d->jscValue); |
1345 return result; |
1090 } |
1346 } |
1091 } |
1347 case QScriptValuePrivate::Number: |
1092 case QScriptValuePrivate::Number: |
1348 return QScript::ToInt32(d->numberValue); |
1093 return QScript::ToInt32(d->numberValue); |
1349 case QScriptValuePrivate::String: |
1094 case QScriptValuePrivate::String: |
1350 return QScript::ToInt32(((JSC::UString)d->stringValue).toDouble()); |
1095 return QScript::ToInt32(d->stringValue); |
1351 } |
1096 } |
1352 return 0; |
1097 return 0; |
1353 } |
1098 } |
1354 |
1099 |
1355 /*! |
1100 /*! |
1369 Q_D(const QScriptValue); |
1114 Q_D(const QScriptValue); |
1370 if (!d) |
1115 if (!d) |
1371 return 0; |
1116 return 0; |
1372 switch (d->type) { |
1117 switch (d->type) { |
1373 case QScriptValuePrivate::JavaScriptCore: { |
1118 case QScriptValuePrivate::JavaScriptCore: { |
1374 JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; |
1119 if (d->engine) { |
1375 JSC::JSValue savedException; |
1120 QScript::APIShim shim(d->engine); |
1376 QScriptValuePrivate::saveException(exec, &savedException); |
1121 return QScriptEnginePrivate::toUInt32(d->engine->currentFrame, d->jscValue); |
1377 quint32 result = d->jscValue.toUInt32(exec); |
1122 } else { |
1378 QScriptValuePrivate::restoreException(exec, savedException); |
1123 return QScriptEnginePrivate::toUInt32(0, d->jscValue); |
1379 return result; |
1124 } |
1380 } |
1125 } |
1381 case QScriptValuePrivate::Number: |
1126 case QScriptValuePrivate::Number: |
1382 return QScript::ToUint32(d->numberValue); |
1127 return QScript::ToUInt32(d->numberValue); |
1383 case QScriptValuePrivate::String: |
1128 case QScriptValuePrivate::String: |
1384 return QScript::ToUint32(((JSC::UString)d->stringValue).toDouble()); |
1129 return QScript::ToUInt32(d->stringValue); |
1385 } |
1130 } |
1386 return 0; |
1131 return 0; |
1387 } |
1132 } |
1388 |
1133 |
1389 /*! |
1134 /*! |
1403 Q_D(const QScriptValue); |
1148 Q_D(const QScriptValue); |
1404 if (!d) |
1149 if (!d) |
1405 return 0; |
1150 return 0; |
1406 switch (d->type) { |
1151 switch (d->type) { |
1407 case QScriptValuePrivate::JavaScriptCore: { |
1152 case QScriptValuePrivate::JavaScriptCore: { |
1408 // ### no equivalent function in JSC |
1153 if (d->engine) { |
1409 return QScript::ToUint16(toNumber()); |
1154 QScript::APIShim shim(d->engine); |
1155 return QScriptEnginePrivate::toUInt16(d->engine->currentFrame, d->jscValue); |
|
1156 } else { |
|
1157 return QScriptEnginePrivate::toUInt16(0, d->jscValue); |
|
1158 } |
|
1410 } |
1159 } |
1411 case QScriptValuePrivate::Number: |
1160 case QScriptValuePrivate::Number: |
1412 return QScript::ToUint16(d->numberValue); |
1161 return QScript::ToUInt16(d->numberValue); |
1413 case QScriptValuePrivate::String: |
1162 case QScriptValuePrivate::String: |
1414 return QScript::ToUint16(((JSC::UString)d->stringValue).toDouble()); |
1163 return QScript::ToUInt16(d->stringValue); |
1415 } |
1164 } |
1416 return 0; |
1165 return 0; |
1417 } |
1166 } |
1418 |
1167 |
1419 /*! |
1168 /*! |
1433 Q_D(const QScriptValue); |
1182 Q_D(const QScriptValue); |
1434 if (!d) |
1183 if (!d) |
1435 return 0; |
1184 return 0; |
1436 switch (d->type) { |
1185 switch (d->type) { |
1437 case QScriptValuePrivate::JavaScriptCore: { |
1186 case QScriptValuePrivate::JavaScriptCore: { |
1438 JSC::ExecState *exec = d->engine ? d->engine->currentFrame : 0; |
1187 if (d->engine) { |
1439 JSC::JSValue savedException; |
1188 QScript::APIShim shim(d->engine); |
1440 QScriptValuePrivate::saveException(exec, &savedException); |
1189 return QScriptEnginePrivate::toInteger(d->engine->currentFrame, d->jscValue); |
1441 qsreal result = d->jscValue.toInteger(exec); |
1190 } else { |
1442 QScriptValuePrivate::restoreException(exec, savedException); |
1191 return QScriptEnginePrivate::toInteger(0, d->jscValue); |
1443 return result; |
1192 } |
1444 } |
1193 } |
1445 case QScriptValuePrivate::Number: |
1194 case QScriptValuePrivate::Number: |
1446 return QScript::ToInteger(d->numberValue); |
1195 return QScript::ToInteger(d->numberValue); |
1447 case QScriptValuePrivate::String: |
1196 case QScriptValuePrivate::String: |
1448 return QScript::ToInteger(((JSC::UString)d->stringValue).toDouble()); |
1197 return QScript::ToInteger(d->stringValue); |
1449 } |
1198 } |
1450 return 0; |
1199 return 0; |
1451 } |
1200 } |
1452 |
1201 |
1453 /*! |
1202 /*! |
1476 { |
1225 { |
1477 Q_D(const QScriptValue); |
1226 Q_D(const QScriptValue); |
1478 if (!d) |
1227 if (!d) |
1479 return QVariant(); |
1228 return QVariant(); |
1480 switch (d->type) { |
1229 switch (d->type) { |
1481 case QScriptValuePrivate::JavaScriptCore: |
1230 case QScriptValuePrivate::JavaScriptCore: { |
1482 if (isObject()) { |
1231 if (d->engine) { |
1483 if (isVariant()) |
1232 QScript::APIShim shim(d->engine); |
1484 return d->variantValue(); |
1233 return QScriptEnginePrivate::toVariant(d->engine->currentFrame, d->jscValue); |
1485 #ifndef QT_NO_QOBJECT |
1234 } else { |
1486 else if (isQObject()) |
1235 return QScriptEnginePrivate::toVariant(0, d->jscValue); |
1487 return qVariantFromValue(toQObject()); |
|
1488 #endif |
|
1489 else if (isDate()) |
|
1490 return QVariant(toDateTime()); |
|
1491 #ifndef QT_NO_REGEXP |
|
1492 else if (isRegExp()) |
|
1493 return QVariant(toRegExp()); |
|
1494 #endif |
|
1495 else if (isArray()) |
|
1496 return QScriptEnginePrivate::variantListFromArray(*this); |
|
1497 else if (QScriptDeclarativeClass *dc = QScriptDeclarativeClass::scriptClass(*this)) |
|
1498 return dc->toVariant(QScriptDeclarativeClass::object(*this)); |
|
1499 // try to convert to primitive |
|
1500 JSC::ExecState *exec = d->engine->currentFrame; |
|
1501 JSC::JSValue savedException; |
|
1502 QScriptValuePrivate::saveException(exec, &savedException); |
|
1503 JSC::JSValue prim = d->jscValue.toPrimitive(exec); |
|
1504 QScriptValuePrivate::restoreException(exec, savedException); |
|
1505 if (!prim.isObject()) |
|
1506 return d->engine->scriptValueFromJSCValue(prim).toVariant(); |
|
1507 } else if (isNumber()) { |
|
1508 return QVariant(toNumber()); |
|
1509 } else if (isString()) { |
|
1510 return QVariant(toString()); |
|
1511 } else if (isBool()) { |
|
1512 return QVariant(toBool()); |
|
1513 } |
1236 } |
1514 return QVariant(); |
1237 } |
1515 case QScriptValuePrivate::Number: |
1238 case QScriptValuePrivate::Number: |
1516 return QVariant(d->numberValue); |
1239 return QVariant(d->numberValue); |
1517 case QScriptValuePrivate::String: |
1240 case QScriptValuePrivate::String: |
1518 return QVariant(d->stringValue); |
1241 return QVariant(d->stringValue); |
1519 } |
1242 } |
1541 \sa isDate() |
1264 \sa isDate() |
1542 */ |
1265 */ |
1543 QDateTime QScriptValue::toDateTime() const |
1266 QDateTime QScriptValue::toDateTime() const |
1544 { |
1267 { |
1545 Q_D(const QScriptValue); |
1268 Q_D(const QScriptValue); |
1546 if (!isDate()) |
1269 if (!d || !d->engine) |
1547 return QDateTime(); |
1270 return QDateTime(); |
1548 qsreal t = static_cast<JSC::DateInstance*>(JSC::asObject(d->jscValue))->internalNumber(); |
1271 return QScriptEnginePrivate::toDateTime(d->engine->currentFrame, d->jscValue); |
1549 return QScript::ToDateTime(t, Qt::LocalTime); |
|
1550 } |
1272 } |
1551 |
1273 |
1552 #ifndef QT_NO_REGEXP |
1274 #ifndef QT_NO_REGEXP |
1553 /*! |
1275 /*! |
1554 Returns the QRegExp representation of this value. |
1276 Returns the QRegExp representation of this value. |
1558 \sa isRegExp() |
1280 \sa isRegExp() |
1559 */ |
1281 */ |
1560 QRegExp QScriptValue::toRegExp() const |
1282 QRegExp QScriptValue::toRegExp() const |
1561 { |
1283 { |
1562 Q_D(const QScriptValue); |
1284 Q_D(const QScriptValue); |
1563 if (!isRegExp()) |
1285 if (!d || !d->engine) |
1564 return QRegExp(); |
1286 return QRegExp(); |
1565 QString pattern = d->property(QLatin1String("source"), QScriptValue::ResolvePrototype).toString(); |
1287 return QScriptEnginePrivate::toRegExp(d->engine->currentFrame, d->jscValue); |
1566 Qt::CaseSensitivity kase = Qt::CaseSensitive; |
|
1567 if (d->property(QLatin1String("ignoreCase"), QScriptValue::ResolvePrototype).toBool()) |
|
1568 kase = Qt::CaseInsensitive; |
|
1569 return QRegExp(pattern, kase, QRegExp::RegExp2); |
|
1570 } |
1288 } |
1571 #endif // QT_NO_REGEXP |
1289 #endif // QT_NO_REGEXP |
1572 |
1290 |
1573 /*! |
1291 /*! |
1574 If this QScriptValue is a QObject, returns the QObject pointer |
1292 If this QScriptValue is a QObject, returns the QObject pointer |
1581 \sa isQObject() |
1299 \sa isQObject() |
1582 */ |
1300 */ |
1583 QObject *QScriptValue::toQObject() const |
1301 QObject *QScriptValue::toQObject() const |
1584 { |
1302 { |
1585 Q_D(const QScriptValue); |
1303 Q_D(const QScriptValue); |
1586 if (isQObject()) { |
1304 if (!d || !d->engine) |
1587 QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(d->jscValue)); |
1305 return 0; |
1588 QScriptObjectDelegate *delegate = object->delegate(); |
1306 return QScriptEnginePrivate::toQObject(d->engine->currentFrame, d->jscValue); |
1589 if (delegate->type() == QScriptObjectDelegate::DeclarativeClassObject) |
|
1590 return static_cast<QScript::DeclarativeObjectDelegate*>(delegate)->scriptClass()->toQObject(QScriptDeclarativeClass::object(*this)); |
|
1591 return static_cast<QScript::QObjectDelegate*>(delegate)->value(); |
|
1592 } else if (isVariant()) { |
|
1593 QVariant var = toVariant(); |
|
1594 int type = var.userType(); |
|
1595 if ((type == QMetaType::QObjectStar) || (type == QMetaType::QWidgetStar)) |
|
1596 return *reinterpret_cast<QObject* const *>(var.constData()); |
|
1597 } |
|
1598 return 0; |
|
1599 } |
1307 } |
1600 |
1308 |
1601 /*! |
1309 /*! |
1602 If this QScriptValue is a QMetaObject, returns the QMetaObject pointer |
1310 If this QScriptValue is a QMetaObject, returns the QMetaObject pointer |
1603 that the QScriptValue represents; otherwise, returns 0. |
1311 that the QScriptValue represents; otherwise, returns 0. |
1605 \sa isQMetaObject() |
1313 \sa isQMetaObject() |
1606 */ |
1314 */ |
1607 const QMetaObject *QScriptValue::toQMetaObject() const |
1315 const QMetaObject *QScriptValue::toQMetaObject() const |
1608 { |
1316 { |
1609 Q_D(const QScriptValue); |
1317 Q_D(const QScriptValue); |
1610 if (isQMetaObject()) |
1318 if (!d || !d->engine) |
1611 return static_cast<QScript::QMetaObjectWrapperObject*>(JSC::asObject(d->jscValue))->value(); |
1319 return 0; |
1612 return 0; |
1320 return QScriptEnginePrivate::toQMetaObject(d->engine->currentFrame, d->jscValue); |
1613 } |
1321 } |
1614 |
1322 |
1615 /*! |
1323 /*! |
1616 Sets the value of this QScriptValue's property with the given \a name to |
1324 Sets the value of this QScriptValue's property with the given \a name to |
1617 the given \a value. |
1325 the given \a value. |
1641 const PropertyFlags &flags) |
1349 const PropertyFlags &flags) |
1642 { |
1350 { |
1643 Q_D(QScriptValue); |
1351 Q_D(QScriptValue); |
1644 if (!d || !d->isObject()) |
1352 if (!d || !d->isObject()) |
1645 return; |
1353 return; |
1646 JSC::ExecState *exec = d->engine->currentFrame; |
1354 QScript::APIShim shim(d->engine); |
1647 d->setProperty(JSC::Identifier(exec, name), value, flags); |
1355 QScriptEnginePrivate *valueEngine = QScriptValuePrivate::getEngine(value); |
1356 if (valueEngine && (valueEngine != d->engine)) { |
|
1357 qWarning("QScriptValue::setProperty(%s) failed: " |
|
1358 "cannot set value created in a different engine", |
|
1359 qPrintable(name)); |
|
1360 return; |
|
1361 } |
|
1362 JSC::JSValue jsValue = d->engine->scriptValueToJSCValue(value); |
|
1363 d->setProperty(name, jsValue, flags); |
|
1648 } |
1364 } |
1649 |
1365 |
1650 /*! |
1366 /*! |
1651 Returns the value of this QScriptValue's property with the given \a name, |
1367 Returns the value of this QScriptValue's property with the given \a name, |
1652 using the given \a mode to resolve the property. |
1368 using the given \a mode to resolve the property. |
1666 const ResolveFlags &mode) const |
1382 const ResolveFlags &mode) const |
1667 { |
1383 { |
1668 Q_D(const QScriptValue); |
1384 Q_D(const QScriptValue); |
1669 if (!d || !d->isObject()) |
1385 if (!d || !d->isObject()) |
1670 return QScriptValue(); |
1386 return QScriptValue(); |
1671 return d->property(name, mode); |
1387 QScript::APIShim shim(d->engine); |
1388 return d->engine->scriptValueFromJSCValue(d->property(name, mode)); |
|
1672 } |
1389 } |
1673 |
1390 |
1674 /*! |
1391 /*! |
1675 \overload |
1392 \overload |
1676 |
1393 |
1688 const ResolveFlags &mode) const |
1405 const ResolveFlags &mode) const |
1689 { |
1406 { |
1690 Q_D(const QScriptValue); |
1407 Q_D(const QScriptValue); |
1691 if (!d || !d->isObject()) |
1408 if (!d || !d->isObject()) |
1692 return QScriptValue(); |
1409 return QScriptValue(); |
1693 return d->property(arrayIndex, mode); |
1410 return d->engine->scriptValueFromJSCValue(d->property(arrayIndex, mode)); |
1694 } |
1411 } |
1695 |
1412 |
1696 /*! |
1413 /*! |
1697 \overload |
1414 \overload |
1698 |
1415 |
1715 && (QScriptValuePrivate::getEngine(value) != d->engine)) { |
1432 && (QScriptValuePrivate::getEngine(value) != d->engine)) { |
1716 qWarning("QScriptValue::setProperty() failed: " |
1433 qWarning("QScriptValue::setProperty() failed: " |
1717 "cannot set value created in a different engine"); |
1434 "cannot set value created in a different engine"); |
1718 return; |
1435 return; |
1719 } |
1436 } |
1720 JSC::ExecState *exec = d->engine->currentFrame; |
1437 JSC::JSValue jsValue = d->engine->scriptValueToJSCValue(value); |
1721 JSC::JSValue jscValue = d->engine->scriptValueToJSCValue(value); |
1438 d->setProperty(arrayIndex, jsValue, flags); |
1722 if (!jscValue) { |
|
1723 JSC::asObject(d->jscValue)->deleteProperty(exec, arrayIndex, /*checkDontDelete=*/false); |
|
1724 } else { |
|
1725 if ((flags & QScriptValue::PropertyGetter) || (flags & QScriptValue::PropertySetter)) { |
|
1726 // fall back to string-based setProperty(), since there is no |
|
1727 // JSC::JSObject::defineGetter(unsigned) |
|
1728 d->setProperty(JSC::Identifier::from(exec, arrayIndex), value, flags); |
|
1729 } else { |
|
1730 if (flags != QScriptValue::KeepExistingFlags) { |
|
1731 // if (JSC::asObject(d->jscValue)->hasOwnProperty(exec, arrayIndex)) |
|
1732 // JSC::asObject(d->jscValue)->deleteProperty(exec, arrayIndex); |
|
1733 unsigned attribs = 0; |
|
1734 if (flags & QScriptValue::ReadOnly) |
|
1735 attribs |= JSC::ReadOnly; |
|
1736 if (flags & QScriptValue::SkipInEnumeration) |
|
1737 attribs |= JSC::DontEnum; |
|
1738 if (flags & QScriptValue::Undeletable) |
|
1739 attribs |= JSC::DontDelete; |
|
1740 attribs |= flags & QScriptValue::UserRange; |
|
1741 JSC::asObject(d->jscValue)->putWithAttributes(exec, arrayIndex, jscValue, attribs); |
|
1742 } else { |
|
1743 JSC::asObject(d->jscValue)->put(exec, arrayIndex, jscValue); |
|
1744 } |
|
1745 } |
|
1746 } |
|
1747 } |
1439 } |
1748 |
1440 |
1749 /*! |
1441 /*! |
1750 \since 4.4 |
1442 \since 4.4 |
1751 |
1443 |
1762 const ResolveFlags &mode) const |
1454 const ResolveFlags &mode) const |
1763 { |
1455 { |
1764 Q_D(const QScriptValue); |
1456 Q_D(const QScriptValue); |
1765 if (!d || !d->isObject() || !QScriptStringPrivate::isValid(name)) |
1457 if (!d || !d->isObject() || !QScriptStringPrivate::isValid(name)) |
1766 return QScriptValue(); |
1458 return QScriptValue(); |
1767 return d->property(name.d_ptr->identifier, mode); |
1459 QScript::APIShim shim(d->engine); |
1460 return d->engine->scriptValueFromJSCValue(d->property(name.d_ptr->identifier, mode)); |
|
1768 } |
1461 } |
1769 |
1462 |
1770 /*! |
1463 /*! |
1771 \since 4.4 |
1464 \since 4.4 |
1772 |
1465 |
1785 const PropertyFlags &flags) |
1478 const PropertyFlags &flags) |
1786 { |
1479 { |
1787 Q_D(QScriptValue); |
1480 Q_D(QScriptValue); |
1788 if (!d || !d->isObject() || !QScriptStringPrivate::isValid(name)) |
1481 if (!d || !d->isObject() || !QScriptStringPrivate::isValid(name)) |
1789 return; |
1482 return; |
1790 d->setProperty(name.d_ptr->identifier, value, flags); |
1483 QScriptEnginePrivate *valueEngine = QScriptValuePrivate::getEngine(value); |
1484 if (valueEngine && (valueEngine != d->engine)) { |
|
1485 qWarning("QScriptValue::setProperty(%s) failed: " |
|
1486 "cannot set value created in a different engine", |
|
1487 qPrintable(name.toString())); |
|
1488 return; |
|
1489 } |
|
1490 QScript::APIShim shim(d->engine); |
|
1491 JSC::JSValue jsValue = d->engine->scriptValueToJSCValue(value); |
|
1492 d->setProperty(name.d_ptr->identifier, jsValue, flags); |
|
1791 } |
1493 } |
1792 |
1494 |
1793 /*! |
1495 /*! |
1794 Returns the flags of the property with the given \a name, using the |
1496 Returns the flags of the property with the given \a name, using the |
1795 given \a mode to resolve the property. |
1497 given \a mode to resolve the property. |
1800 const ResolveFlags &mode) const |
1502 const ResolveFlags &mode) const |
1801 { |
1503 { |
1802 Q_D(const QScriptValue); |
1504 Q_D(const QScriptValue); |
1803 if (!d || !d->isObject()) |
1505 if (!d || !d->isObject()) |
1804 return 0; |
1506 return 0; |
1507 QScript::APIShim shim(d->engine); |
|
1805 JSC::ExecState *exec = d->engine->currentFrame; |
1508 JSC::ExecState *exec = d->engine->currentFrame; |
1806 return d->propertyFlags(JSC::Identifier(exec, name), mode); |
1509 return d->propertyFlags(JSC::Identifier(exec, name), mode); |
1807 |
1510 |
1808 } |
1511 } |
1809 |
1512 |
1849 */ |
1552 */ |
1850 QScriptValue QScriptValue::call(const QScriptValue &thisObject, |
1553 QScriptValue QScriptValue::call(const QScriptValue &thisObject, |
1851 const QScriptValueList &args) |
1554 const QScriptValueList &args) |
1852 { |
1555 { |
1853 Q_D(const QScriptValue); |
1556 Q_D(const QScriptValue); |
1854 if (!d || !d->isJSC()) |
1557 if (!d || !d->isObject()) |
1855 return QScriptValue(); |
1558 return QScriptValue(); |
1559 QScript::APIShim shim(d->engine); |
|
1856 JSC::JSValue callee = d->jscValue; |
1560 JSC::JSValue callee = d->jscValue; |
1857 JSC::CallData callData; |
1561 JSC::CallData callData; |
1858 JSC::CallType callType = callee.getCallData(callData); |
1562 JSC::CallType callType = callee.getCallData(callData); |
1859 if (callType == JSC::CallTypeNone) |
1563 if (callType == JSC::CallTypeNone) |
1860 return QScriptValue(); |
1564 return QScriptValue(); |
1889 } |
1593 } |
1890 } |
1594 } |
1891 JSC::ArgList jscArgs(argsVector.data(), argsVector.size()); |
1595 JSC::ArgList jscArgs(argsVector.data(), argsVector.size()); |
1892 |
1596 |
1893 JSC::JSValue savedException; |
1597 JSC::JSValue savedException; |
1894 QScriptValuePrivate::saveException(exec, &savedException); |
1598 QScriptEnginePrivate::saveException(exec, &savedException); |
1895 JSC::JSValue result = JSC::call(exec, callee, callType, callData, jscThisObject, jscArgs); |
1599 JSC::JSValue result = JSC::call(exec, callee, callType, callData, jscThisObject, jscArgs); |
1896 if (exec->hadException()) { |
1600 if (exec->hadException()) { |
1897 result = exec->exception(); |
1601 result = exec->exception(); |
1898 } else { |
1602 } else { |
1899 QScriptValuePrivate::restoreException(exec, savedException); |
1603 QScriptEnginePrivate::restoreException(exec, savedException); |
1900 } |
1604 } |
1901 return d->engine->scriptValueFromJSCValue(result); |
1605 return d->engine->scriptValueFromJSCValue(result); |
1902 } |
1606 } |
1903 |
1607 |
1904 /*! |
1608 /*! |
1926 */ |
1630 */ |
1927 QScriptValue QScriptValue::call(const QScriptValue &thisObject, |
1631 QScriptValue QScriptValue::call(const QScriptValue &thisObject, |
1928 const QScriptValue &arguments) |
1632 const QScriptValue &arguments) |
1929 { |
1633 { |
1930 Q_D(QScriptValue); |
1634 Q_D(QScriptValue); |
1931 if (!d || !d->isJSC()) |
1635 if (!d || !d->isObject()) |
1932 return QScriptValue(); |
1636 return QScriptValue(); |
1637 QScript::APIShim shim(d->engine); |
|
1933 JSC::JSValue callee = d->jscValue; |
1638 JSC::JSValue callee = d->jscValue; |
1934 JSC::CallData callData; |
1639 JSC::CallData callData; |
1935 JSC::CallType callType = callee.getCallData(callData); |
1640 JSC::CallType callType = callee.getCallData(callData); |
1936 if (callType == JSC::CallTypeNone) |
1641 if (callType == JSC::CallTypeNone) |
1937 return QScriptValue(); |
1642 return QScriptValue(); |
1969 return d->engine->scriptValueFromJSCValue(JSC::throwError(exec, JSC::TypeError, "Arguments must be an array")); |
1674 return d->engine->scriptValueFromJSCValue(JSC::throwError(exec, JSC::TypeError, "Arguments must be an array")); |
1970 } |
1675 } |
1971 } |
1676 } |
1972 |
1677 |
1973 JSC::JSValue savedException; |
1678 JSC::JSValue savedException; |
1974 QScriptValuePrivate::saveException(exec, &savedException); |
1679 QScriptEnginePrivate::saveException(exec, &savedException); |
1975 JSC::JSValue result = JSC::call(exec, callee, callType, callData, jscThisObject, applyArgs); |
1680 JSC::JSValue result = JSC::call(exec, callee, callType, callData, jscThisObject, applyArgs); |
1976 if (exec->hadException()) { |
1681 if (exec->hadException()) { |
1977 result = exec->exception(); |
1682 result = exec->exception(); |
1978 } else { |
1683 } else { |
1979 QScriptValuePrivate::restoreException(exec, savedException); |
1684 QScriptEnginePrivate::restoreException(exec, savedException); |
1980 } |
1685 } |
1981 return d->engine->scriptValueFromJSCValue(result); |
1686 return d->engine->scriptValueFromJSCValue(result); |
1982 } |
1687 } |
1983 |
1688 |
1984 /*! |
1689 /*! |
2000 \sa call(), QScriptEngine::newObject() |
1705 \sa call(), QScriptEngine::newObject() |
2001 */ |
1706 */ |
2002 QScriptValue QScriptValue::construct(const QScriptValueList &args) |
1707 QScriptValue QScriptValue::construct(const QScriptValueList &args) |
2003 { |
1708 { |
2004 Q_D(const QScriptValue); |
1709 Q_D(const QScriptValue); |
2005 if (!d || !d->isJSC()) |
1710 if (!d || !d->isObject()) |
2006 return QScriptValue(); |
1711 return QScriptValue(); |
1712 QScript::APIShim shim(d->engine); |
|
2007 JSC::JSValue callee = d->jscValue; |
1713 JSC::JSValue callee = d->jscValue; |
2008 JSC::ConstructData constructData; |
1714 JSC::ConstructData constructData; |
2009 JSC::ConstructType constructType = callee.getConstructData(constructData); |
1715 JSC::ConstructType constructType = callee.getConstructData(constructData); |
2010 if (constructType == JSC::ConstructTypeNone) |
1716 if (constructType == JSC::ConstructTypeNone) |
2011 return QScriptValue(); |
1717 return QScriptValue(); |
2021 } |
1727 } |
2022 |
1728 |
2023 JSC::ArgList jscArgs(argsVector.data(), argsVector.size()); |
1729 JSC::ArgList jscArgs(argsVector.data(), argsVector.size()); |
2024 |
1730 |
2025 JSC::JSValue savedException; |
1731 JSC::JSValue savedException; |
2026 QScriptValuePrivate::saveException(exec, &savedException); |
1732 QScriptEnginePrivate::saveException(exec, &savedException); |
2027 JSC::JSObject *result = JSC::construct(exec, callee, constructType, constructData, jscArgs); |
1733 JSC::JSObject *result = JSC::construct(exec, callee, constructType, constructData, jscArgs); |
2028 if (exec->hadException()) { |
1734 if (exec->hadException()) { |
2029 result = JSC::asObject(exec->exception()); |
1735 result = JSC::asObject(exec->exception()); |
2030 } else { |
1736 } else { |
2031 QScriptValuePrivate::restoreException(exec, savedException); |
1737 QScriptEnginePrivate::restoreException(exec, savedException); |
2032 } |
1738 } |
2033 return d->engine->scriptValueFromJSCValue(result); |
1739 return d->engine->scriptValueFromJSCValue(result); |
2034 } |
1740 } |
2035 |
1741 |
2036 /*! |
1742 /*! |
2049 \sa call(), QScriptEngine::newObject(), QScriptContext::argumentsObject() |
1755 \sa call(), QScriptEngine::newObject(), QScriptContext::argumentsObject() |
2050 */ |
1756 */ |
2051 QScriptValue QScriptValue::construct(const QScriptValue &arguments) |
1757 QScriptValue QScriptValue::construct(const QScriptValue &arguments) |
2052 { |
1758 { |
2053 Q_D(QScriptValue); |
1759 Q_D(QScriptValue); |
2054 if (!d || !d->isJSC()) |
1760 if (!d || !d->isObject()) |
2055 return QScriptValue(); |
1761 return QScriptValue(); |
1762 QScript::APIShim shim(d->engine); |
|
2056 JSC::JSValue callee = d->jscValue; |
1763 JSC::JSValue callee = d->jscValue; |
2057 JSC::ConstructData constructData; |
1764 JSC::ConstructData constructData; |
2058 JSC::ConstructType constructType = callee.getConstructData(constructData); |
1765 JSC::ConstructType constructType = callee.getConstructData(constructData); |
2059 if (constructType == JSC::ConstructTypeNone) |
1766 if (constructType == JSC::ConstructTypeNone) |
2060 return QScriptValue(); |
1767 return QScriptValue(); |
2080 return d->engine->scriptValueFromJSCValue(JSC::throwError(exec, JSC::TypeError, "Arguments must be an array")); |
1787 return d->engine->scriptValueFromJSCValue(JSC::throwError(exec, JSC::TypeError, "Arguments must be an array")); |
2081 } |
1788 } |
2082 } |
1789 } |
2083 |
1790 |
2084 JSC::JSValue savedException; |
1791 JSC::JSValue savedException; |
2085 QScriptValuePrivate::saveException(exec, &savedException); |
1792 QScriptEnginePrivate::saveException(exec, &savedException); |
2086 JSC::JSObject *result = JSC::construct(exec, callee, constructType, constructData, applyArgs); |
1793 JSC::JSObject *result = JSC::construct(exec, callee, constructType, constructData, applyArgs); |
2087 if (exec->hadException()) { |
1794 if (exec->hadException()) { |
2088 if (exec->exception().isObject()) |
1795 if (exec->exception().isObject()) |
2089 result = JSC::asObject(exec->exception()); |
1796 result = JSC::asObject(exec->exception()); |
2090 } else { |
1797 } else { |
2091 QScriptValuePrivate::restoreException(exec, savedException); |
1798 QScriptEnginePrivate::restoreException(exec, savedException); |
2092 } |
1799 } |
2093 return d->engine->scriptValueFromJSCValue(result); |
1800 return d->engine->scriptValueFromJSCValue(result); |
2094 } |
1801 } |
2095 |
1802 |
2096 /*! |
1803 /*! |
2235 \sa toVariant(), QScriptEngine::newVariant() |
1942 \sa toVariant(), QScriptEngine::newVariant() |
2236 */ |
1943 */ |
2237 bool QScriptValue::isVariant() const |
1944 bool QScriptValue::isVariant() const |
2238 { |
1945 { |
2239 Q_D(const QScriptValue); |
1946 Q_D(const QScriptValue); |
2240 if (!d || !d->isJSC() || !d->jscValue.inherits(&QScriptObject::info)) |
1947 if (!d || !d->isJSC()) |
2241 return false; |
1948 return false; |
2242 QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(d->jscValue)); |
1949 return QScriptEnginePrivate::isVariant(d->jscValue); |
2243 QScriptObjectDelegate *delegate = object->delegate(); |
|
2244 return (delegate && (delegate->type() == QScriptObjectDelegate::Variant)); |
|
2245 } |
1950 } |
2246 |
1951 |
2247 /*! |
1952 /*! |
2248 Returns true if this QScriptValue is a QObject; otherwise returns |
1953 Returns true if this QScriptValue is a QObject; otherwise returns |
2249 false. |
1954 false. |
2254 \sa toQObject(), QScriptEngine::newQObject() |
1959 \sa toQObject(), QScriptEngine::newQObject() |
2255 */ |
1960 */ |
2256 bool QScriptValue::isQObject() const |
1961 bool QScriptValue::isQObject() const |
2257 { |
1962 { |
2258 Q_D(const QScriptValue); |
1963 Q_D(const QScriptValue); |
2259 if (!d || !d->isJSC() || !d->jscValue.inherits(&QScriptObject::info)) |
1964 if (!d || !d->isJSC()) |
2260 return false; |
1965 return false; |
2261 QScriptObject *object = static_cast<QScriptObject*>(JSC::asObject(d->jscValue)); |
1966 return QScriptEnginePrivate::isQObject(d->jscValue); |
2262 QScriptObjectDelegate *delegate = object->delegate(); |
|
2263 return (delegate && (delegate->type() == QScriptObjectDelegate::QtObject || |
|
2264 (delegate->type() == QScriptObjectDelegate::DeclarativeClassObject && |
|
2265 static_cast<QScript::DeclarativeObjectDelegate*>(delegate)->scriptClass()->isQObject()))); |
|
2266 } |
1967 } |
2267 |
1968 |
2268 /*! |
1969 /*! |
2269 Returns true if this QScriptValue is a QMetaObject; otherwise returns |
1970 Returns true if this QScriptValue is a QMetaObject; otherwise returns |
2270 false. |
1971 false. |
2272 \sa toQMetaObject(), QScriptEngine::newQMetaObject() |
1973 \sa toQMetaObject(), QScriptEngine::newQMetaObject() |
2273 */ |
1974 */ |
2274 bool QScriptValue::isQMetaObject() const |
1975 bool QScriptValue::isQMetaObject() const |
2275 { |
1976 { |
2276 Q_D(const QScriptValue); |
1977 Q_D(const QScriptValue); |
2277 if (!d || !d->isObject()) |
1978 if (!d || !d->isJSC()) |
2278 return false; |
1979 return false; |
2279 return JSC::asObject(d->jscValue)->inherits(&QScript::QMetaObjectWrapperObject::info); |
1980 return QScriptEnginePrivate::isQMetaObject(d->jscValue); |
2280 } |
1981 } |
2281 |
1982 |
2282 /*! |
1983 /*! |
2283 Returns true if this QScriptValue is valid; otherwise returns |
1984 Returns true if this QScriptValue is valid; otherwise returns |
2284 false. |
1985 false. |
2305 if (d->jscValue.inherits(&QScriptObject::info)) { |
2006 if (d->jscValue.inherits(&QScriptObject::info)) { |
2306 QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(d->jscValue)); |
2007 QScriptObject *scriptObject = static_cast<QScriptObject*>(JSC::asObject(d->jscValue)); |
2307 return d->engine->scriptValueFromJSCValue(scriptObject->data()); |
2008 return d->engine->scriptValueFromJSCValue(scriptObject->data()); |
2308 } else { |
2009 } else { |
2309 // ### make hidden property |
2010 // ### make hidden property |
2310 return d->property(QLatin1String("__qt_data__"), QScriptValue::ResolveLocal); |
2011 return property(QLatin1String("__qt_data__"), QScriptValue::ResolveLocal); |
2311 } |
2012 } |
2312 } |
2013 } |
2313 |
2014 |
2314 /*! |
2015 /*! |
2315 \since 4.4 |
2016 \since 4.4 |
2316 |
2017 |
2317 Sets the internal \a data of this QScriptValue object. You can use |
2018 Sets the internal \a data of this QScriptValue object. You can use |
2318 this function to set object-specific data that won't be directly |
2019 this function to set object-specific data that won't be directly |
2319 accessible to scripts, but may be retrieved in C++ using the data() |
2020 accessible to scripts, but may be retrieved in C++ using the data() |
2320 function. |
2021 function. |
2022 |
|
2023 \sa QScriptEngine::reportAdditionalMemoryCost() |
|
2321 */ |
2024 */ |
2322 void QScriptValue::setData(const QScriptValue &data) |
2025 void QScriptValue::setData(const QScriptValue &data) |
2323 { |
2026 { |
2324 Q_D(QScriptValue); |
2027 Q_D(QScriptValue); |
2325 if (!d || !d->isObject()) |
2028 if (!d || !d->isObject()) |