Number::Number(QScriptEnginePrivate *eng): Core(eng, QLatin1String("Number"), QScriptClassInfo::NumberType) { newNumber(&publicPrototype, 0); eng->newConstructor(&ctor, this, publicPrototype); addPrototypeFunction(QLatin1String("toString"), method_toString, 0); addPrototypeFunction(QLatin1String("toLocaleString"), method_toLocaleString, 0); addPrototypeFunction(QLatin1String("valueOf"), method_valueOf, 0); addPrototypeFunction(QLatin1String("toFixed"), method_toFixed, 0); addPrototypeFunction(QLatin1String("toExponential"), method_toExponential, 0); addPrototypeFunction(QLatin1String("toPrecision"), method_toPrecision, 0); QScriptValue::PropertyFlags flags = QScriptValue::Undeletable | QScriptValue::ReadOnly | QScriptValue::SkipInEnumeration; ctor.setProperty(QLatin1String("NaN"), QScriptValueImpl(eng, qSNaN()), flags); ctor.setProperty(QLatin1String("NEGATIVE_INFINITY"), QScriptValueImpl(eng, -qInf()), flags); ctor.setProperty(QLatin1String("POSITIVE_INFINITY"), QScriptValueImpl(eng, qInf()), flags); ctor.setProperty(QLatin1String("MAX_VALUE"), QScriptValueImpl(eng, 1.7976931348623158e+308), flags); #ifdef __INTEL_COMPILER # pragma warning( push ) # pragma warning(disable: 239) #endif ctor.setProperty(QLatin1String("MIN_VALUE"), QScriptValueImpl(eng, 5e-324), flags); #ifdef __INTEL_COMPILER # pragma warning( pop ) #endif }
QScriptValueImpl Number::method_toString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo) { QScriptValueImpl self = context->thisObject(); if (self.classInfo() != classInfo) return context->throwError(QScriptContext::TypeError, QLatin1String("Number.prototype.toString")); QScriptValueImpl arg = context->argument(0); if (!arg.isUndefined()) { int radix = arg.toInt32(); if (radix < 2 || radix > 36) return context->throwError(QString::fromLatin1("Number.prototype.toString: %0 is not a valid radix") .arg(radix)); if (radix != 10) { QString str; qsreal num = self.internalValue().toInteger(); do { char c = (char)::fmod(num, radix); if (c < 10) c += '0'; else c = c - 10 + 'a'; str.prepend(QLatin1Char(c)); num = ::floor(num / radix); } while (num != 0); return QScriptValueImpl(eng, str); } } QString str = self.internalValue().toString(); return (QScriptValueImpl(eng, str)); }
QScriptValueImpl Math::method_ceil(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) { qsreal v = context->argument(0).toNumber(); if (v < 0.0 && v > -1.0) return QScriptValueImpl(eng, copySign(0, -1.0)); return (QScriptValueImpl(eng, ::ceil(v))); }
QScriptValueImpl Math::method_log(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) { qsreal v = context->argument(0).toNumber(); if (v < 0) return QScriptValueImpl(eng, qSNaN()); return (QScriptValueImpl(eng, ::log(v))); }
QScriptValueImpl Math::method_tan(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) { qsreal v = context->argument(0).toNumber(); if (v == 0.0) return QScriptValueImpl(eng, v); return (QScriptValueImpl(eng, ::tan(v))); }
QScriptValueImpl Math::method_abs(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) { qsreal v = context->argument(0).toNumber(); if (v == 0) // 0 | -0 return (QScriptValueImpl(eng, 0)); else return (QScriptValueImpl(eng, v < 0 ? -v : v)); }
QScriptValueImpl Math::method_exp(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) { qsreal v = context->argument(0).toNumber(); if (qIsInf(v)) { if (copySign(1.0, v) == -1.0) return QScriptValueImpl(eng, 0); else return QScriptValueImpl(eng, qInf()); } return (QScriptValueImpl(eng, ::exp(v))); }
QScriptValueImpl RegExp::method_exec(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo) { QScriptValueImpl self = context->thisObject(); if (self.classInfo() != classInfo) { return throwThisObjectTypeError( context, QLatin1String("RegExp.prototype.exec")); } Instance *rx_data = Instance::get(self, classInfo); Q_ASSERT(rx_data != 0); QString S = context->argument(0).toString(); int length = S.length(); QScriptValueImpl lastIndex = self.property(QLatin1String("lastIndex")); int i = lastIndex.isValid() ? int (lastIndex.toInteger()) : 0; bool global = self.property(QLatin1String("global")).toBoolean(); if (! global) i = 0; if (i < 0 || i >= length) return (eng->nullValue()); #ifndef QT_NO_REGEXP int index = rx_data->value.indexIn(S, i); if (index == -1) #endif // QT_NO_REGEXP return eng->nullValue(); #ifndef QT_NO_REGEXP int e = index + rx_data->value.matchedLength(); if (global) self.setProperty(QLatin1String("lastIndex"), QScriptValueImpl(e)); QScript::Array elts(eng); QStringList capturedTexts = rx_data->value.capturedTexts(); for (int i = 0; i < capturedTexts.count(); ++i) elts.assign(i, QScriptValueImpl(eng, capturedTexts.at(i))); QScriptValueImpl r = eng->newArray(elts); r.setProperty(QLatin1String("index"), QScriptValueImpl(index)); r.setProperty(QLatin1String("input"), QScriptValueImpl(eng, S)); return r; #endif // QT_NO_REGEXP }
QScriptValueImpl Object::method_propertyIsEnumerable(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) { bool result = false; if (context->thisObject().isObject() && (context->argumentCount() > 0)) { QScriptValueImpl arg = context->argument(0); QScriptNameIdImpl *id = 0; if (arg.isString()) id = arg.stringValue(); if (! id || ! id->unique) { QString str = arg.toString(); id = eng->nameId(str); } QScript::Member member; QScriptValueImpl base; QScriptValueImpl self = context->thisObject(); if (self.resolve(id, &member, &base, QScriptValue::ResolveLocal, QScript::Read)) { result = ! member.dontEnum(); if (result) { QScriptValueImpl tmp; base.get(member, &tmp); result = tmp.isValid(); } } } return (QScriptValueImpl(result)); }
QScriptValueImpl Object::method_hasOwnProperty(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) { bool result = false; if (context->thisObject().isObject() && (context->argumentCount() > 0)) { QScriptValueImpl arg = context->argument(0); QScriptNameIdImpl *id = 0; if (arg.isString()) id = arg.stringValue(); if (! id || ! id->unique) { QString str = arg.toString(); id = eng->nameId(str); } QScript::Member member; QScriptValueImpl base; QScriptValueImpl self = context->thisObject(); if (self.resolve(id, &member, &base, QScriptValue::ResolveLocal, QScript::Read)) result = true; } return (QScriptValueImpl(result)); }
QScriptValueImpl Math::method_sqrt(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) { qsreal v = context->argument(0).toNumber(); return (QScriptValueImpl(eng, ::sqrt(v))); }
QScriptValueImpl Math::method_round(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) { qsreal v = context->argument(0).toNumber(); v = copySign(::floor(v + 0.5), v); return (QScriptValueImpl(eng, v)); }
void QScriptValueIteratorImpl::previous() { (void)hasPrevious(); // sync the previous-element info m_object = m_foundObject; m_member = m_foundMember; m_foundObject = QScriptValueImpl(); m_foundMember.invalidate(); }
void QScriptValueIteratorImpl::next() { (void)hasNext(); // sync the next-element info m_object = m_foundObject; m_member = m_foundMember; m_foundObject = QScriptValueImpl(); m_foundMember.invalidate(); }
QScriptValueImpl Object::method_toString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) { QScriptValueImpl glo = eng->globalObject(); QString s = QLatin1String("[object "); QScriptValueImpl self = context->thisObject(); s += self.classInfo()->name(); s += QLatin1String("]"); return (QScriptValueImpl(eng, s)); }
QScriptValueImpl Number::method_toLocaleString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo) { QScriptValueImpl self = context->thisObject(); if (self.classInfo() != classInfo) return context->throwError(QScriptContext::TypeError, QLatin1String("Number.prototype.toLocaleString")); QString str = self.internalValue().toString(); return (QScriptValueImpl(eng, str)); }
/*! \fn QScriptValue::QScriptValue(QScriptEngine *engine, qsreal value) \obsolete Constructs a new QScriptValue with the qsreal \a value and registers it with the script \a engine. */ QScriptValue::QScriptValue(QScriptEngine *engine, qsreal val) { if (engine) { QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(engine); d_ptr = eng_p->registerValue(QScriptValueImpl(val)); d_ptr->ref.ref(); } else { d_ptr = 0; } }
QScriptValueImpl Function::method_toString(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) { QScriptValueImpl self = context->thisObject(); if (QScriptFunction *foo = self.toFunction()) { QString code = foo->toString(context); return QScriptValueImpl(eng, code); } return context->throwError(QScriptContext::TypeError, QLatin1String("Function.prototype.toString")); }
void Error::newError(QScriptValueImpl *result, const QScriptValueImpl &proto, const QString &message) { QScriptEnginePrivate *eng_p = engine(); if (!result->isValid()) eng_p->newObject(result, proto, classInfo()); else result->setClassInfo(classInfo()); result->setProperty(QLatin1String("message"), QScriptValueImpl(eng_p, message)); }
QScriptValueImpl Math::method_max(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) { qsreal mx = -qInf(); for (int i = 0; i < context->argumentCount(); ++i) { qsreal x = context->argument(i).toNumber(); if (x > mx || qIsNaN(x)) mx = x; } return (QScriptValueImpl(eng, mx)); }
QScriptValueImpl Variant::method_valueOf(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo) { if (Instance *instance = Instance::get(context->thisObject(), classInfo)) { QVariant v = instance->value; switch (v.type ()) { case QVariant::Invalid: return eng->undefinedValue(); case QVariant::String: return (QScriptValueImpl(eng, v.toString())); case QVariant::Int: return (QScriptValueImpl(v.toInt())); case QVariant::Bool: return (QScriptValueImpl(v.toBool())); case QVariant::Double: return (QScriptValueImpl(v.toDouble())); // ### hmmm case QVariant::Char: return (QScriptValueImpl(v.toChar().unicode())); case QVariant::UInt: return (QScriptValueImpl(v.toUInt())); default: return context->thisObject(); } // switch } return context->thisObject(); }
void Error::newErrorPrototype(QScriptValueImpl *result, const QScriptValueImpl &proto, QScriptValueImpl &ztor, const QString &name) { newError(result, proto); result->setProperty(QLatin1String("name"), QScriptValueImpl(engine(), name)); result->setProperty(QLatin1String("constructor"), ztor, QScriptValue::Undeletable | QScriptValue::SkipInEnumeration); ztor.setProperty(QLatin1String("prototype"), *result, QScriptValue::Undeletable | QScriptValue::ReadOnly | QScriptValue::SkipInEnumeration); }
void RegExp::initRegExp(QScriptValueImpl *result, #ifndef QT_NO_REGEXP const QRegExp &rx, #else const QString &pattern, #endif int flags) { Instance *instance = new Instance(); #ifndef QT_NO_REGEXP instance->value = rx; #else instance->pattern = pattern; #endif instance->flags = flags; result->setObjectData(instance); bool global = (flags & Global) != 0; bool ignoreCase = (flags & IgnoreCase) != 0; bool multiline = (flags & Multiline) != 0; QScriptValue::PropertyFlags propertyFlags = QScriptValue::SkipInEnumeration | QScriptValue::Undeletable | QScriptValue::ReadOnly; result->setProperty(QLatin1String("global"), QScriptValueImpl(global), propertyFlags); result->setProperty(QLatin1String("ignoreCase"), QScriptValueImpl(ignoreCase), propertyFlags); result->setProperty(QLatin1String("multiline"), QScriptValueImpl(multiline), propertyFlags); #ifndef QT_NO_REGEXP const QString &pattern = rx.pattern(); #endif result->setProperty(QLatin1String("source"), QScriptValueImpl(engine(), pattern), propertyFlags); result->setProperty(QLatin1String("lastIndex"), QScriptValueImpl(0), propertyFlags & ~QScriptValue::ReadOnly); }
void Math::construct(QScriptValueImpl *object, QScriptEnginePrivate *eng) { QScriptClassInfo *classInfo = eng->registerClass(QLatin1String("Math")); Math *instance = new Math(eng, classInfo); eng->newObject(object, classInfo); object->setObjectData(instance); QScriptValue::PropertyFlags flags = QScriptValue::Undeletable | QScriptValue::ReadOnly | QScriptValue::SkipInEnumeration; object->setProperty(QLatin1String("E"), QScriptValueImpl(eng, ::exp(1.0)), flags); object->setProperty(QLatin1String("LN2"), QScriptValueImpl(eng, ::log(2.0)), flags); object->setProperty(QLatin1String("LN10"), QScriptValueImpl(eng, ::log(10.0)), flags); object->setProperty(QLatin1String("LOG2E"), QScriptValueImpl(eng, 1.0/::log(2.0)), flags); object->setProperty(QLatin1String("LOG10E"), QScriptValueImpl(eng, 1.0/::log(10.0)), flags); object->setProperty(QLatin1String("PI"), QScriptValueImpl(eng, qt_PI), flags); object->setProperty(QLatin1String("SQRT1_2"), QScriptValueImpl(eng, ::sqrt(0.5)), flags); object->setProperty(QLatin1String("SQRT2"), QScriptValueImpl(eng, ::sqrt(2.0)), flags); flags = QScriptValue::SkipInEnumeration; addFunction(*object, QLatin1String("abs"), method_abs, 1, flags); addFunction(*object, QLatin1String("acos"), method_acos, 1, flags); addFunction(*object, QLatin1String("asin"), method_asin, 0, flags); addFunction(*object, QLatin1String("atan"), method_atan, 1, flags); addFunction(*object, QLatin1String("atan2"), method_atan2, 2, flags); addFunction(*object, QLatin1String("ceil"), method_ceil, 1, flags); addFunction(*object, QLatin1String("cos"), method_cos, 1, flags); addFunction(*object, QLatin1String("exp"), method_exp, 1, flags); addFunction(*object, QLatin1String("floor"), method_floor, 1, flags); addFunction(*object, QLatin1String("log"), method_log, 1, flags); addFunction(*object, QLatin1String("max"), method_max, 2, flags); addFunction(*object, QLatin1String("min"), method_min, 2, flags); addFunction(*object, QLatin1String("pow"), method_pow, 2, flags); addFunction(*object, QLatin1String("random"), method_random, 0, flags); addFunction(*object, QLatin1String("round"), method_round, 1, flags); addFunction(*object, QLatin1String("sin"), method_sin, 1, flags); addFunction(*object, QLatin1String("sqrt"), method_sqrt, 1, flags); addFunction(*object, QLatin1String("tan"), method_tan, 1, flags); }
QScriptValueImpl QScriptValueIteratorImpl::value() const { if (!m_member.isValid()) return QScriptValueImpl(); QScriptValueImpl result; m_object.get(m_member, &result); if (m_member.isGetterOrSetter()) { // find and call the getter QScriptValueImpl getter; if (m_member.isObjectProperty() && !m_member.isGetter()) { QScript::Member mb; QScriptObject *obj = m_object.m_object_value; mb.object(m_member.nameId(), obj->memberCount(), 0); if (!obj->findGetter(&mb)) return QScriptValueImpl(); m_object.get(mb, &getter); } else { getter = result; } result = getter.call(m_object); } return result; }
QScriptValueImpl Math::method_min(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) { qsreal mx = qInf(); for (int i = 0; i < context->argumentCount(); ++i) { qsreal x = context->argument(i).toNumber(); if ((x == 0 && mx == x && copySign(1.0, x) == -1.0) || (x < mx) || qIsNaN(x)) { mx = x; } } return (QScriptValueImpl(eng, mx)); }
void Enumeration::Instance::next(QScriptContextPrivate *context, QScriptValueImpl *result) { QScriptEnginePrivate *eng = context->engine(); Q_ASSERT(it != 0); it->next(); QScript::Member *member = it->member(); if (member->isObjectProperty() || member->nameId()) eng->newNameId(result, member->nameId()); else if (member->isNativeProperty() && !member->nameId()) *result = QScriptValueImpl(uint(member->id())); else *result = eng->undefinedValue(); }
QScriptValueImpl Number::method_toPrecision(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *classInfo) { QScriptValueImpl self = context->thisObject(); if (self.classInfo() != classInfo) return context->throwError(QScriptContext::TypeError, QLatin1String("Number.prototype.toPrecision")); qsreal fdigits = 0; if (context->argumentCount() > 0) fdigits = context->argument(0).toInteger(); qsreal v = self.internalValue().toNumber(); return (QScriptValueImpl(eng, QString::number(v, 'g', int (fdigits)))); }
void QScriptValueIteratorImpl::toBack() { m_member.invalidate(); m_foundObject = QScriptValueImpl(); m_foundMember.invalidate(); if (!m_classDataIterator) { QScriptClassData *data = m_object.classInfo()->data(); if (data) m_classDataIterator = data->newIterator(m_object); } if (m_classDataIterator) m_classDataIterator->toBack(); else m_searchIndex = m_object.memberCount(); m_searchClassDataIterator = (m_classDataIterator != 0); }
QScriptValueImpl Math::method_atan2(QScriptContextPrivate *context, QScriptEnginePrivate *eng, QScriptClassInfo *) { qsreal v1 = context->argument(0).toNumber(); qsreal v2 = context->argument(1).toNumber(); #ifdef Q_OS_WINCE if (v1 == 0.0) { const bool v1MinusZero = _copysign(1.0, v1) < 0.0; const bool v2MinusZero = (v2 == 0 && _copysign(1.0, v2) < 0.0); if ((v1MinusZero && v2MinusZero) || (v1MinusZero && v2 == -1.0)) return QScriptValueImpl(eng, -qt_PI); if (v2MinusZero) return QScriptValueImpl(eng, qt_PI); if (v1MinusZero && v2 == 1.0) return QScriptValueImpl(eng, -0.0); #if defined(_X86_) if (v2 == 0.0 && (v1MinusZero || (!v1MinusZero && !v2MinusZero))) return QScriptValueImpl(eng, 0.0); #endif } #endif #if defined(Q_OS_WINCE) && defined(_X86_) if (v1 == -1.0 && !_finite(v2) && _copysign(1.0, v2) > 0.0) return QScriptValueImpl(eng, -0.0); #endif if ((v1 < 0) && qIsFinite(v1) && qIsInf(v2) && (copySign(1.0, v2) == 1.0)) return QScriptValueImpl(eng, copySign(0, -1.0)); if ((v1 == 0.0) && (v2 == 0.0)) { if ((copySign(1.0, v1) == 1.0) && (copySign(1.0, v2) == -1.0)) return QScriptValueImpl(eng, qt_PI); else if ((copySign(1.0, v1) == -1.0) && (copySign(1.0, v2) == -1.0)) return QScriptValueImpl(eng, -qt_PI); } return (QScriptValueImpl(eng, ::atan2(v1, v2))); }