namespace QQmlJS {
namespace VM {
-QString numberToString(double num, int radix = 10)
+QString __qmljs_numberToString(double num, int radix)
{
if (std::isnan(num)) {
return QStringLiteral("NaN");
Value __qmljs_string_from_number(ExecutionContext *ctx, double number)
{
- String *string = ctx->engine->newString(numberToString(number, 10));
+ String *string = ctx->engine->newString(__qmljs_numberToString(number, 10));
return Value::fromString(string);
}
double __qmljs_to_number(const Value &value);
Value __qmljs_to_string(const Value &value, ExecutionContext *ctx);
Q_QML_EXPORT String *__qmljs_convert_to_string(ExecutionContext *ctx, const Value &value);
+QString __qmljs_numberToString(double num, int radix = 10);
Value __qmljs_to_object(ExecutionContext *ctx, const Value &value);
Object *__qmljs_convert_to_object(ExecutionContext *ctx, const Value &value);
{
Local<Value> result;
QQmlJS::VM::Object *o = ConstValuePtr(this)->asObject();
- assert(o);
+ if (!o)
+ return Local<Value>();
return Local<Value>::New(Value::fromVmValue(QQmlJS::VM::Value::fromObject(o->prototype)));
}
if (!p)
return false;
QQmlJS::VM::Object *o = ConstValuePtr(this)->asObject();
- assert(o);
+ if (!o)
+ return false;
+
o->prototype = p;
return true;
}
#include "qscriptisolate_p.h"
#include "qv8engine_p.h"
+#include "private/qv4engine_p.h"
+#include "private/qv4mm_p.h"
+#include "private/qv4globalobject_p.h"
+
#include <QtCore/qdatetime.h>
#include <QtCore/qmetaobject.h>
#include <QtCore/qstringlist.h>
*/
void QJSEngine::collectGarbage()
{
- Q_D(QJSEngine);
- QScriptIsolate api(d);
- d->collectGarbage();
+ d->m_v4Engine->memoryManager->runGC();
}
/*!
*/
QJSValue QJSEngine::evaluate(const QString& program, const QString& fileName, int lineNumber)
{
- Q_D(QJSEngine);
- QScriptIsolate api(d, QScriptIsolate::NotNullEngine);
- v8::HandleScope handleScope;
- return d->evaluate(program, fileName, qmlSourceCoordinate(lineNumber));
+ try {
+ QQmlJS::VM::Function *f = QQmlJS::VM::EvalFunction::parseSource(d->m_v4Engine->current, fileName, program, QQmlJS::Codegen::EvalCode,
+ d->m_v4Engine->current->strictMode, true);
+ if (!f)
+ return new QJSValuePrivate(d->m_v4Engine, d->m_v4Engine->newSyntaxErrorObject(d->m_v4Engine->current, 0));
+
+ QQmlJS::VM::Value result = d->m_v4Engine->run(f);
+ return new QJSValuePrivate(d->m_v4Engine, result);
+ } catch (QQmlJS::VM::Exception& ex) {
+ ex.accept(d->m_v4Engine->current);
+ return new QJSValuePrivate(d->m_v4Engine, ex.value());
+ }
}
/*!
*/
QJSValue QJSEngine::newObject()
{
- Q_D(QJSEngine);
- QScriptIsolate api(d, QScriptIsolate::NotNullEngine);
- v8::HandleScope handleScope;
- QQmlJS::VM::ExecutionEngine *engine = d->m_v4Engine;
- return new QJSValuePrivate(engine, QQmlJS::VM::Value::fromObject(engine->newObject()));
+ return new QJSValuePrivate(d->m_v4Engine, d->m_v4Engine->newObject());
}
/*!
*/
QJSValue QJSEngine::newArray(uint length)
{
- Q_D(QJSEngine);
- QScriptIsolate api(d, QScriptIsolate::NotNullEngine);
- v8::HandleScope handleScope;
- return QJSValuePrivate::get(d->newArray(length));
+ QQmlJS::VM::ArrayObject *array = d->m_v4Engine->newArrayObject(d->m_v4Engine->current);
+ array->setArrayLength(length);
+ return new QJSValuePrivate(d->m_v4Engine, array);
}
/*!
*/
QJSValue QJSEngine::newQObject(QObject *object)
{
+ // ###
Q_D(QJSEngine);
QScriptIsolate api(d, QScriptIsolate::NotNullEngine);
v8::HandleScope handleScope;
*/
QJSValue QJSEngine::globalObject() const
{
- Q_D(const QJSEngine);
- QScriptIsolate api(d, QScriptIsolate::NotNullEngine);
- v8::HandleScope handleScope;
- return d->scriptValueFromInternal(d->global());
+ return new QJSValuePrivate(d->m_v4Engine, d->m_v4Engine->globalObject);
}
/*!
*reinterpret_cast<double*>(ptr) = vp->value.toNumber();
return true;
case QMetaType::QString:
- *reinterpret_cast<QString*>(ptr) = vp->value.toString(engine->m_v4Engine->current)->toQString();
+ *reinterpret_cast<QString*>(ptr) = value.toString();
return true;
case QMetaType::Float:
*reinterpret_cast<float*>(ptr) = vp->value.toNumber();
*/
QString QJSValue::toString() const
{
- if (!d->engine)
- // ###
- return QString();
- return d->value.toString(d->engine->current)->toQString();
+ // have to check these here as converting those to a VM::String requires a context
+ // (which we don't always have for those types)
+ if (d->value.isUndefined())
+ return QStringLiteral("undefined");
+ else if (d->value.isNull())
+ return QStringLiteral("null");
+ else if (d->value.isBoolean()) {
+ if (d->value.booleanValue())
+ return QStringLiteral("true");
+ else
+ return QStringLiteral("false");
+ }
+ else if (d->value.isNumber())
+ return __qmljs_numberToString(d->value.asDouble());
+
+ QQmlJS::VM::ExecutionContext *ctx = d->engine ? d->engine->current : 0;
+ try {
+ return d->value.toString(ctx)->toQString();
+ } catch (Exception &e) {
+ e.accept(ctx);
+ return e.value().toString(ctx)->toQString();
+ }
}
/*!
*/
double QJSValue::toNumber() const
{
- return d->value.toNumber();
+ QQmlJS::VM::ExecutionContext *ctx = d->engine ? d->engine->current : 0;
+ try {
+ return d->value.toNumber();
+ } catch (Exception &e) {
+ e.accept(ctx);
+ return 0;
+ }
}
/*!
*/
bool QJSValue::toBool() const
{
- return d->value.toBoolean();
+ QQmlJS::VM::ExecutionContext *ctx = d->engine ? d->engine->current : 0;
+ try {
+ return d->value.toBoolean();
+ } catch (Exception &e) {
+ e.accept(ctx);
+ return false;
+ }
}
/*!
*/
qint32 QJSValue::toInt() const
{
- return d->value.toInt32();
+ QQmlJS::VM::ExecutionContext *ctx = d->engine ? d->engine->current : 0;
+ try {
+ return d->value.toInt32();
+ } catch (Exception &e) {
+ e.accept(ctx);
+ return 0;
+ }
}
/*!
*/
quint32 QJSValue::toUInt() const
{
- return d->value.toUInt32();
+ QQmlJS::VM::ExecutionContext *ctx = d->engine ? d->engine->current : 0;
+ try {
+ return d->value.toUInt32();
+ } catch (Exception &e) {
+ e.accept(ctx);
+ return 0;
+ }
}
/*!
arguments[i] = args.at(i).d->getValue(engine);
Value result;
+ QQmlJS::VM::ExecutionContext *ctx = d->engine->current;
try {
- result = f->call(d->engine->current, Value::fromObject(d->engine->globalObject), arguments.data(), arguments.size());
+ result = f->call(ctx, Value::fromObject(d->engine->globalObject), arguments.data(), arguments.size());
} catch (Exception &e) {
+ e.accept(ctx);
result = e.value();
}
arguments[i] = args.at(i).d->getValue(engine);
Value result;
+ QQmlJS::VM::ExecutionContext *ctx = d->engine->current;
try {
- result = f->call(d->engine->current, instance.d->getValue(engine), arguments.data(), arguments.size());
+ result = f->call(ctx, instance.d->getValue(engine), arguments.data(), arguments.size());
} catch (Exception &e) {
+ e.accept(ctx);
result = e.value();
}
arguments[i] = args.at(i).d->getValue(engine);
Value result;
+ QQmlJS::VM::ExecutionContext *ctx = d->engine->current;
try {
- result = f->construct(d->engine->current, arguments.data(), arguments.size());
+ result = f->construct(ctx, arguments.data(), arguments.size());
} catch (Exception &e) {
+ e.accept(ctx);
result = e.value();
}
if (!o)
return QJSValue();
- String *s = d->engine->newIdentifier(name);
- QQmlJS::VM::Value v = o->get(d->engine->current, s);
- return new QJSValuePrivate(d->engine, v);
+ String *s = d->engine->newString(name);
+ uint idx = s->asArrayIndex();
+ if (idx < UINT_MAX)
+ return property(idx);
+
+ s->makeIdentifier(d->engine->current);
+ QQmlJS::VM::ExecutionContext *ctx = d->engine->current;
+ try {
+ QQmlJS::VM::Value v = o->get(ctx, s);
+ return new QJSValuePrivate(d->engine, v);
+ } catch (QQmlJS::VM::Exception &e) {
+ e.accept(ctx);
+ return QJSValue();
+ }
}
/*!
if (!o)
return QJSValue();
- QQmlJS::VM::Value v = o->getIndexed(d->engine->current, arrayIndex);
- return new QJSValuePrivate(d->engine, v);
+ QQmlJS::VM::ExecutionContext *ctx = d->engine->current;
+ try {
+ QQmlJS::VM::Value v = o->getIndexed(ctx, arrayIndex);
+ return new QJSValuePrivate(d->engine, v);
+ } catch (QQmlJS::VM::Exception &e) {
+ e.accept(ctx);
+ return QJSValue();
+ }
}
/*!
if (!o)
return;
- String *s = d->engine->newIdentifier(name);
- o->put(d->engine->current, s, value.d->value);
+ String *s = d->engine->newString(name);
+ uint idx = s->asArrayIndex();
+ if (idx < UINT_MAX) {
+ setProperty(idx, value);
+ return;
+ }
+
+ QQmlJS::VM::ExecutionContext *ctx = d->engine->current;
+ s->makeIdentifier(ctx);
+ try {
+ o->put(ctx, s, value.d->value);
+ } catch (QQmlJS::VM::Exception &e) {
+ e.accept(ctx);
+ }
}
/*!
if (!o)
return;
- o->putIndexed(d->engine->current, arrayIndex, value.d->value);
+ QQmlJS::VM::ExecutionContext *ctx = d->engine->current;
+ try {
+ o->putIndexed(ctx, arrayIndex, value.d->value);
+ } catch (QQmlJS::VM::Exception &e) {
+ e.accept(ctx);
+ }
}
/*!
: PersistentValuePrivate(e, v)
, string(QString())
{}
+ QJSValuePrivate(QQmlJS::VM::ExecutionEngine *e, QQmlJS::VM::Object *o)
+ : PersistentValuePrivate(e, QQmlJS::VM::Value::fromObject(o))
+ , string(QString())
+ {}
+ QJSValuePrivate(QQmlJS::VM::ExecutionEngine *e, QQmlJS::VM::String *s)
+ : PersistentValuePrivate(e, QQmlJS::VM::Value::fromString(s))
+ , string(QString())
+ {}
QJSValuePrivate(const QQmlJS::VM::Value &v)
: PersistentValuePrivate(v)
, string(QString())
QJSValueIteratorPrivate::QJSValueIteratorPrivate(const QJSValue &v)
: value(v)
- , iterator(QJSValuePrivate::get(v)->value.asObject(), QQmlJS::VM::ObjectIterator::EnumberableOnly)
+ , iterator(QJSValuePrivate::get(v)->value.asObject(), QQmlJS::VM::ObjectIterator::NoFlags)
, currentValue(0)
, currentName(0)
, currentIndex(UINT_MAX)
*/
bool QJSValueIterator::hasNext() const
{
+ if (!QJSValuePrivate::get(d_ptr->value)->value.isObject())
+ return false;
return d_ptr->nextValue != 0;
}
*/
bool QJSValueIterator::next()
{
+ if (!QJSValuePrivate::get(d_ptr->value)->value.isObject())
+ return false;
d_ptr->currentValue = d_ptr->nextValue;
d_ptr->currentName = d_ptr->nextName;
d_ptr->currentIndex = d_ptr->nextIndex;
d_ptr->currentAttributes = d_ptr->nextAttributes;
d_ptr->nextValue = d_ptr->iterator.next(&d_ptr->nextName, &d_ptr->nextIndex, &d_ptr->nextAttributes);
+ return d_ptr->nextValue != 0;
}
/*!
*/
QString QJSValueIterator::name() const
{
+ if (!QJSValuePrivate::get(d_ptr->value)->value.isObject())
+ return false;
if (d_ptr->currentName)
return d_ptr->currentName->toQString();
if (d_ptr->currentIndex < UINT_MAX)
*/
QJSValue QJSValueIterator::value() const
{
+ if (!QJSValuePrivate::get(d_ptr->value)->value.isObject())
+ return QJSValue();
if (!d_ptr->currentValue)
return QJSValue();
*/
QJSValueIterator& QJSValueIterator::operator=(QJSValue& object)
{
- d_ptr->iterator = QQmlJS::VM::ObjectIterator(QJSValuePrivate::get(object)->value.asObject(), QQmlJS::VM::ObjectIterator::EnumberableOnly);
+ d_ptr->iterator = QQmlJS::VM::ObjectIterator(QJSValuePrivate::get(object)->value.asObject(), QQmlJS::VM::ObjectIterator::NoFlags);
d_ptr->nextValue = d_ptr->iterator.next(&d_ptr->nextName, &d_ptr->nextIndex, &d_ptr->nextAttributes);
}
$$PWD/qjsvalue.h \
$$PWD/qjsvalue_p.h \
$$PWD/qjsvalueiterator.h \
- $$PWD/qjsvalue_impl_p.h \
$$PWD/qjsconverter_p.h \
$$PWD/qjsconverter_impl_p.h \
$$PWD/qscriptisolate_p.h \
- $$PWD/qjsvalueiterator_p.h \
- $$PWD/qjsvalueiterator_impl_p.h
+ $$PWD/qjsvalueiterator_p.h
"})()");
QVERIFY(!objectObject.isError());
QVERIFY(objectObject.isObject());
- QCOMPARE(objectObject.toString(), QString::fromLatin1("TypeError: Function.prototype.toString is not generic"));
+ QCOMPARE(objectObject.toString(), QString::fromLatin1("TypeError: Type error"));
}
QJSValue inv = QJSValue();