aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4runtime.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/jsruntime/qv4runtime.cpp')
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp804
1 files changed, 435 insertions, 369 deletions
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index b019d4db14..c31de6a9f0 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -1,7 +1,7 @@
/****************************************************************************
**
-** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtQml module of the Qt Toolkit.
**
@@ -10,9 +10,9 @@
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
@@ -23,8 +23,8 @@
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
+** As a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
@@ -35,11 +35,11 @@
#include "qv4runtime_p.h"
#ifndef V4_BOOTSTRAP
#include "qv4object_p.h"
-#include "qv4jsir_p.h"
#include "qv4objectproto_p.h"
#include "qv4globalobject_p.h"
#include "qv4stringobject_p.h"
#include "qv4argumentsobject_p.h"
+#include "qv4objectiterator_p.h"
#include "qv4lookup_p.h"
#include "qv4function_p.h"
#include "private/qlocale_tools_p.h"
@@ -50,16 +50,20 @@
#include <private/qv8engine_p.h>
#endif
-#include <QtCore/qmath.h>
-#include <QtCore/qnumeric.h>
#include <QtCore/QDebug>
-#include <cstdio>
#include <cassert>
-#include <typeinfo>
+#include <cstdio>
#include <stdlib.h>
+#include <wtf/MathExtras.h>
+
#include "../../3rdparty/double-conversion/double-conversion.h"
+#ifdef QV4_COUNT_RUNTIME_FUNCTIONS
+# include <QtCore/QBuffer>
+# include <QtCore/QDebug>
+#endif // QV4_COUNT_RUNTIME_FUNCTIONS
+
QT_BEGIN_NAMESPACE
namespace QV4 {
@@ -144,7 +148,9 @@ struct RuntimeCounters::Data {
};
void dump() const {
- QTextStream outs(stderr, QIODevice::WriteOnly);
+ QBuffer buf;
+ buf.open(QIODevice::WriteOnly);
+ QTextStream outs(&buf);
QList<Line> lines;
foreach (const char *func, counters.keys()) {
const Counters &fCount = counters[func];
@@ -159,7 +165,7 @@ struct RuntimeCounters::Data {
lines.append(line);
}
}
- qSort(lines.begin(), lines.end(), Line::less);
+ std::sort(lines.begin(), lines.end(), Line::less);
outs << lines.size() << " counters:" << endl;
foreach (const Line &line, lines)
outs << qSetFieldWidth(10) << line.count << qSetFieldWidth(0)
@@ -167,6 +173,7 @@ struct RuntimeCounters::Data {
<< " | " << pretty(line.tag1)
<< " | " << pretty(line.tag2)
<< endl;
+ qDebug("%s", buf.data().constData());
}
};
@@ -256,84 +263,92 @@ void RuntimeHelpers::numberToString(QString *result, double num, int radix)
result->prepend(QLatin1Char('-'));
}
-ReturnedValue Runtime::closure(ExecutionContext *ctx, int functionId)
+ReturnedValue Runtime::closure(ExecutionEngine *engine, int functionId)
{
- QV4::Function *clos = ctx->d()->compilationUnit->runtimeFunctions[functionId];
+ QV4::Function *clos = engine->currentContext()->compilationUnit->runtimeFunctions[functionId];
Q_ASSERT(clos);
- return FunctionObject::createScriptFunction(ctx, clos)->asReturnedValue();
+ Scope scope(engine);
+ return FunctionObject::createScriptFunction(ScopedContext(scope, engine->currentContext()), clos)->asReturnedValue();
}
-ReturnedValue Runtime::deleteElement(ExecutionContext *ctx, const ValueRef base, const ValueRef index)
+ReturnedValue Runtime::deleteElement(ExecutionEngine *engine, const Value &base, const Value &index)
{
- Scope scope(ctx);
+ Scope scope(engine);
ScopedObject o(scope, base);
if (o) {
- uint n = index->asArrayIndex();
+ uint n = index.asArrayIndex();
if (n < UINT_MAX) {
return Encode((bool)o->deleteIndexedProperty(n));
}
}
- ScopedString name(scope, index->toString(ctx));
- return Runtime::deleteMember(ctx, base, name.getPointer());
+ ScopedString name(scope, index.toString(engine));
+ return Runtime::deleteMemberString(engine, base, name);
}
-ReturnedValue Runtime::deleteMember(ExecutionContext *ctx, const ValueRef base, String *name)
+ReturnedValue Runtime::deleteMember(ExecutionEngine *engine, const Value &base, int nameIndex)
{
- Scope scope(ctx);
- ScopedObject obj(scope, base->toObject(ctx));
+ Scope scope(engine);
+ ScopedString name(scope, engine->currentContext()->compilationUnit->runtimeStrings[nameIndex]);
+ return deleteMemberString(engine, base, name);
+}
+
+ReturnedValue Runtime::deleteMemberString(ExecutionEngine *engine, const Value &base, String *name)
+{
+ Scope scope(engine);
+ ScopedObject obj(scope, base.toObject(engine));
if (scope.engine->hasException)
return Encode::undefined();
return Encode(obj->deleteProperty(name));
}
-ReturnedValue Runtime::deleteName(ExecutionContext *ctx, String *name)
+ReturnedValue Runtime::deleteName(ExecutionEngine *engine, int nameIndex)
{
- Scope scope(ctx);
+ Scope scope(engine);
+ ScopedString name(scope, engine->currentContext()->compilationUnit->runtimeStrings[nameIndex]);
+ ScopedContext ctx(scope, engine->currentContext());
return Encode(ctx->deleteProperty(name));
}
-QV4::ReturnedValue Runtime::instanceof(ExecutionContext *ctx, const ValueRef left, const ValueRef right)
+QV4::ReturnedValue Runtime::instanceof(ExecutionEngine *engine, const Value &left, const Value &right)
{
- // As nothing in this method can call into the memory manager, avoid using a Scope
- // for performance reasons
-
- FunctionObject *f = right->asFunctionObject();
+ Scope scope(engine);
+ ScopedFunctionObject f(scope, right.asFunctionObject());
if (!f)
- return ctx->throwTypeError();
+ return engine->throwTypeError();
- if (f->subtype() == FunctionObject::BoundFunction)
- f = static_cast<BoundFunction *>(f)->target();
+ if (f->isBoundFunction())
+ f = static_cast<BoundFunction *>(f.getPointer())->target();
- Object *v = left->asObject();
+ ScopedObject v(scope, left.asObject());
if (!v)
return Encode(false);
- Object *o = QV4::Value::fromReturnedValue(f->protoProperty()).asObject();
+ ScopedObject o(scope, f->protoProperty());
if (!o)
- return ctx->throwTypeError();
+ return engine->throwTypeError();
while (v) {
v = v->prototype();
if (!v)
break;
- else if (o == v)
+ else if (o->d() == v->d())
return Encode(true);
}
return Encode(false);
}
-QV4::ReturnedValue Runtime::in(ExecutionContext *ctx, const ValueRef left, const ValueRef right)
+QV4::ReturnedValue Runtime::in(ExecutionEngine *engine, const Value &left, const Value &right)
{
- if (!right->isObject())
- return ctx->throwTypeError();
- Scope scope(ctx);
- ScopedString s(scope, left->toString(ctx));
+ if (!right.isObject())
+ return engine->throwTypeError();
+ Scope scope(engine);
+ ScopedString s(scope, left.toString(engine));
if (scope.hasException())
return Encode::undefined();
- bool r = right->objectValue()->hasProperty(s.getPointer());
+ bool r = right.objectValue()->hasProperty(s);
return Encode(r);
}
@@ -358,11 +373,11 @@ double RuntimeHelpers::stringToNumber(const QString &string)
return d;
}
-Returned<String> *RuntimeHelpers::stringFromNumber(ExecutionContext *ctx, double number)
+Heap::String *RuntimeHelpers::stringFromNumber(ExecutionEngine *engine, double number)
{
QString qstr;
RuntimeHelpers::numberToString(&qstr, number, 10);
- return ctx->engine()->newString(qstr);
+ return engine->newString(qstr);
}
ReturnedValue RuntimeHelpers::objectDefaultValue(Object *object, int typeHint)
@@ -384,8 +399,7 @@ ReturnedValue RuntimeHelpers::objectDefaultValue(Object *object, int typeHint)
if (typeHint == NUMBER_HINT)
qSwap(meth1, meth2);
- ExecutionContext *ctx = engine->currentContext();
- Scope scope(ctx);
+ Scope scope(engine);
ScopedCallData callData(scope, 0);
callData->thisObject = object;
@@ -406,161 +420,162 @@ ReturnedValue RuntimeHelpers::objectDefaultValue(Object *object, int typeHint)
return r->asReturnedValue();
}
- return ctx->throwTypeError();
+ return engine->throwTypeError();
}
-Returned<Object> *RuntimeHelpers::convertToObject(ExecutionContext *ctx, const ValueRef value)
+Heap::Object *RuntimeHelpers::convertToObject(ExecutionEngine *engine, const Value &value)
{
- assert(!value->isObject());
- switch (value->type()) {
+ Q_ASSERT(!value.isObject());
+ switch (value.type()) {
case Value::Undefined_Type:
case Value::Null_Type:
- ctx->throwTypeError();
+ engine->throwTypeError();
return 0;
case Value::Boolean_Type:
- return ctx->engine()->newBooleanObject(value);
+ return engine->newBooleanObject(value.booleanValue());
case Value::Managed_Type:
- Q_ASSERT(value->isString());
- return ctx->engine()->newStringObject(value);
+ Q_ASSERT(value.isString());
+ return engine->newStringObject(value);
case Value::Integer_Type:
default: // double
- return ctx->engine()->newNumberObject(value);
+ return engine->newNumberObject(value.asDouble());
}
}
-Returned<String> *RuntimeHelpers::convertToString(ExecutionContext *ctx, const ValueRef value)
+Heap::String *RuntimeHelpers::convertToString(ExecutionEngine *engine, const Value &value)
{
- switch (value->type()) {
+ switch (value.type()) {
case Value::Empty_Type:
Q_ASSERT(!"empty Value encountered");
case Value::Undefined_Type:
- return ctx->engine()->id_undefined.ret();
+ return engine->id_undefined->d();
case Value::Null_Type:
- return ctx->engine()->id_null.ret();
+ return engine->id_null->d();
case Value::Boolean_Type:
- if (value->booleanValue())
- return ctx->engine()->id_true.ret();
+ if (value.booleanValue())
+ return engine->id_true->d();
else
- return ctx->engine()->id_false.ret();
+ return engine->id_false->d();
case Value::Managed_Type:
- if (value->isString())
- return value->stringValue()->asReturned<String>();
+ if (value.isString())
+ return value.stringValue()->d();
{
- Scope scope(ctx);
+ Scope scope(engine);
ScopedValue prim(scope, RuntimeHelpers::toPrimitive(value, STRING_HINT));
- return RuntimeHelpers::convertToString(ctx, prim);
+ return RuntimeHelpers::convertToString(engine, prim);
}
case Value::Integer_Type:
- return RuntimeHelpers::stringFromNumber(ctx, value->int_32);
+ return RuntimeHelpers::stringFromNumber(engine, value.int_32);
default: // double
- return RuntimeHelpers::stringFromNumber(ctx, value->doubleValue());
+ return RuntimeHelpers::stringFromNumber(engine, value.doubleValue());
} // switch
}
// This is slightly different from the method above, as
// the + operator requires a slightly different conversion
-static Returned<String> *convert_to_string_add(ExecutionContext *ctx, const ValueRef value)
+static Heap::String *convert_to_string_add(ExecutionEngine *engine, const Value &value)
{
- switch (value->type()) {
+ switch (value.type()) {
case Value::Empty_Type:
Q_ASSERT(!"empty Value encountered");
case Value::Undefined_Type:
- return ctx->engine()->id_undefined.ret();
+ return engine->id_undefined->d();
case Value::Null_Type:
- return ctx->engine()->id_null.ret();
+ return engine->id_null->d();
case Value::Boolean_Type:
- if (value->booleanValue())
- return ctx->engine()->id_true.ret();
+ if (value.booleanValue())
+ return engine->id_true->d();
else
- return ctx->engine()->id_false.ret();
+ return engine->id_false->d();
case Value::Managed_Type:
- if (value->isString())
- return value->stringValue()->asReturned<String>();
+ if (value.isString())
+ return value.stringValue()->d();
{
- Scope scope(ctx);
+ Scope scope(engine);
ScopedValue prim(scope, RuntimeHelpers::toPrimitive(value, PREFERREDTYPE_HINT));
- return RuntimeHelpers::convertToString(ctx, prim);
+ return RuntimeHelpers::convertToString(engine, prim);
}
case Value::Integer_Type:
- return RuntimeHelpers::stringFromNumber(ctx, value->int_32);
+ return RuntimeHelpers::stringFromNumber(engine, value.int_32);
default: // double
- return RuntimeHelpers::stringFromNumber(ctx, value->doubleValue());
+ return RuntimeHelpers::stringFromNumber(engine, value.doubleValue());
} // switch
}
-QV4::ReturnedValue RuntimeHelpers::addHelper(ExecutionContext *ctx, const ValueRef left, const ValueRef right)
+QV4::ReturnedValue RuntimeHelpers::addHelper(ExecutionEngine *engine, const Value &left, const Value &right)
{
- Scope scope(ctx);
+ Scope scope(engine);
ScopedValue pleft(scope, RuntimeHelpers::toPrimitive(left, PREFERREDTYPE_HINT));
ScopedValue pright(scope, RuntimeHelpers::toPrimitive(right, PREFERREDTYPE_HINT));
if (pleft->isString() || pright->isString()) {
if (!pleft->isString())
- pleft = convert_to_string_add(ctx, pleft);
+ pleft = convert_to_string_add(engine, pleft);
if (!pright->isString())
- pright = convert_to_string_add(ctx, pright);
+ pright = convert_to_string_add(engine, pright);
if (scope.engine->hasException)
return Encode::undefined();
if (!pleft->stringValue()->d()->length())
return pright->asReturnedValue();
if (!pright->stringValue()->d()->length())
return pleft->asReturnedValue();
- return (ctx->engine()->memoryManager->alloc<String>(ctx->d()->engine, pleft->stringValue(), pright->stringValue()))->asReturnedValue();
+ return (engine->memoryManager->alloc<String>(pleft->stringValue()->d(), pright->stringValue()->d()))->asReturnedValue();
}
double x = RuntimeHelpers::toNumber(pleft);
double y = RuntimeHelpers::toNumber(pright);
return Encode(x + y);
}
-QV4::ReturnedValue Runtime::addString(QV4::ExecutionContext *ctx, const QV4::ValueRef left, const QV4::ValueRef right)
+QV4::ReturnedValue Runtime::addString(ExecutionEngine *engine, const Value &left, const Value &right)
{
- Q_ASSERT(left->isString() || right->isString());
+ Q_ASSERT(left.isString() || right.isString());
- if (left->isString() && right->isString()) {
- if (!left->stringValue()->d()->length())
- return right->asReturnedValue();
- if (!right->stringValue()->d()->length())
- return left->asReturnedValue();
- return (ctx->engine()->memoryManager->alloc<String>(ctx->d()->engine, left->stringValue(), right->stringValue()))->asReturnedValue();
+ if (left.isString() && right.isString()) {
+ if (!left.stringValue()->d()->length())
+ return right.asReturnedValue();
+ if (!right.stringValue()->d()->length())
+ return left.asReturnedValue();
+ return (engine->memoryManager->alloc<String>(left.stringValue()->d(), right.stringValue()->d()))->asReturnedValue();
}
- Scope scope(ctx);
- ScopedValue pleft(scope, *left);
- ScopedValue pright(scope, *right);
+ Scope scope(engine);
+ ScopedValue pleft(scope, left);
+ ScopedValue pright(scope, right);
if (!pleft->isString())
- pleft = convert_to_string_add(ctx, left);
+ pleft = convert_to_string_add(engine, left);
if (!pright->isString())
- pright = convert_to_string_add(ctx, right);
+ pright = convert_to_string_add(engine, right);
if (scope.engine->hasException)
return Encode::undefined();
if (!pleft->stringValue()->d()->length())
return pright->asReturnedValue();
if (!pright->stringValue()->d()->length())
return pleft->asReturnedValue();
- return (ctx->engine()->memoryManager->alloc<String>(ctx->d()->engine, pleft->stringValue(), pright->stringValue()))->asReturnedValue();
+ return (engine->memoryManager->alloc<String>(pleft->stringValue()->d(), pright->stringValue()->d()))->asReturnedValue();
}
-void Runtime::setProperty(ExecutionContext *ctx, const ValueRef object, String *name, const ValueRef value)
+void Runtime::setProperty(ExecutionEngine *engine, const Value &object, int nameIndex, const Value &value)
{
- Scope scope(ctx);
- ScopedObject o(scope, object->toObject(ctx));
+ Scope scope(engine);
+ ScopedString name(scope, engine->currentContext()->compilationUnit->runtimeStrings[nameIndex]);
+ ScopedObject o(scope, object.toObject(engine));
if (!o)
return;
o->put(name, value);
}
-ReturnedValue Runtime::getElement(ExecutionContext *ctx, const ValueRef object, const ValueRef index)
+ReturnedValue Runtime::getElement(ExecutionEngine *engine, const Value &object, const Value &index)
{
- Scope scope(ctx);
- uint idx = index->asArrayIndex();
+ Scope scope(engine);
+ uint idx = index.asArrayIndex();
- Scoped<Object> o(scope, object);
+ ScopedObject o(scope, object);
if (!o) {
if (idx < UINT_MAX) {
- if (String *str = object->asString()) {
+ if (String *str = object.asString()) {
if (idx >= (uint)str->toQString().length()) {
return Encode::undefined();
}
@@ -569,18 +584,18 @@ ReturnedValue Runtime::getElement(ExecutionContext *ctx, const ValueRef object,
}
}
- if (object->isNullOrUndefined()) {
- QString message = QStringLiteral("Cannot read property '%1' of %2").arg(index->toQStringNoThrow()).arg(object->toQStringNoThrow());
- return ctx->throwTypeError(message);
+ if (object.isNullOrUndefined()) {
+ QString message = QStringLiteral("Cannot read property '%1' of %2").arg(index.toQStringNoThrow()).arg(object.toQStringNoThrow());
+ return engine->throwTypeError(message);
}
- o = RuntimeHelpers::convertToObject(ctx, object);
+ o = RuntimeHelpers::convertToObject(scope.engine, object);
if (!o) // type error
return Encode::undefined();
}
if (idx < UINT_MAX) {
- if (o->arrayData() && !o->arrayData()->hasAttributes()) {
+ if (o->arrayData() && !o->arrayData()->attrs) {
ScopedValue v(scope, o->arrayData()->get(idx));
if (!v->isEmpty())
return v->asReturnedValue();
@@ -589,24 +604,24 @@ ReturnedValue Runtime::getElement(ExecutionContext *ctx, const ValueRef object,
return o->getIndexed(idx);
}
- ScopedString name(scope, index->toString(ctx));
+ ScopedString name(scope, index.toString(engine));
if (scope.hasException())
return Encode::undefined();
- return o->get(name.getPointer());
+ return o->get(name);
}
-void Runtime::setElement(ExecutionContext *ctx, const ValueRef object, const ValueRef index, const ValueRef value)
+void Runtime::setElement(ExecutionEngine *engine, const Value &object, const Value &index, const Value &value)
{
- Scope scope(ctx);
- ScopedObject o(scope, object->toObject(ctx));
+ Scope scope(engine);
+ ScopedObject o(scope, object.toObject(engine));
if (scope.engine->hasException)
return;
- uint idx = index->asArrayIndex();
+ uint idx = index.asArrayIndex();
if (idx < UINT_MAX) {
- if (o->arrayType() == ArrayData::Simple) {
- SimpleArrayData *s = static_cast<SimpleArrayData *>(o->arrayData());
- if (s && idx < s->len() && !s->data(idx).isEmpty()) {
+ if (o->arrayType() == Heap::ArrayData::Simple) {
+ Heap::SimpleArrayData *s = static_cast<Heap::SimpleArrayData *>(o->arrayData());
+ if (s && idx < s->len && !s->data(idx).isEmpty()) {
s->data(idx) = value;
return;
}
@@ -615,92 +630,98 @@ void Runtime::setElement(ExecutionContext *ctx, const ValueRef object, const Val
return;
}
- ScopedString name(scope, index->toString(ctx));
- o->put(name.getPointer(), value);
+ ScopedString name(scope, index.toString(engine));
+ o->put(name, value);
}
-ReturnedValue Runtime::foreachIterator(ExecutionContext *ctx, const ValueRef in)
+ReturnedValue Runtime::foreachIterator(ExecutionEngine *engine, const Value &in)
{
- Scope scope(ctx);
- Scoped<Object> o(scope, (Object *)0);
- if (!in->isNullOrUndefined())
- o = in->toObject(ctx);
- Scoped<Object> it(scope, ctx->engine()->newForEachIteratorObject(ctx, o));
- return it.asReturnedValue();
+ Scope scope(engine);
+ ScopedObject o(scope, (Object *)0);
+ if (!in.isNullOrUndefined())
+ o = in.toObject(engine);
+ return engine->newForEachIteratorObject(o)->asReturnedValue();
}
-ReturnedValue Runtime::foreachNextPropertyName(const ValueRef foreach_iterator)
+ReturnedValue Runtime::foreachNextPropertyName(const Value &foreach_iterator)
{
- Q_ASSERT(foreach_iterator->isObject());
+ Q_ASSERT(foreach_iterator.isObject());
- ForEachIteratorObject *it = static_cast<ForEachIteratorObject *>(foreach_iterator->objectValue());
+ ForEachIteratorObject *it = static_cast<ForEachIteratorObject *>(foreach_iterator.objectValue());
Q_ASSERT(it->as<ForEachIteratorObject>());
return it->nextPropertyName();
}
-void Runtime::setActivationProperty(ExecutionContext *ctx, String *name, const ValueRef value)
+void Runtime::setActivationProperty(ExecutionEngine *engine, int nameIndex, const Value &value)
{
+ Scope scope(engine);
+ ScopedString name(scope, engine->currentContext()->compilationUnit->runtimeStrings[nameIndex]);
+ ScopedContext ctx(scope, engine->currentContext());
ctx->setProperty(name, value);
}
-ReturnedValue Runtime::getProperty(ExecutionContext *ctx, const ValueRef object, String *name)
+ReturnedValue Runtime::getProperty(ExecutionEngine *engine, const Value &object, int nameIndex)
{
- Scope scope(ctx);
+ Scope scope(engine);
+ ScopedString name(scope, engine->currentContext()->compilationUnit->runtimeStrings[nameIndex]);
- Scoped<Object> o(scope, object);
+ ScopedObject o(scope, object);
if (o)
return o->get(name);
- if (object->isNullOrUndefined()) {
- QString message = QStringLiteral("Cannot read property '%1' of %2").arg(name->toQString()).arg(object->toQStringNoThrow());
- return ctx->throwTypeError(message);
+ if (object.isNullOrUndefined()) {
+ QString message = QStringLiteral("Cannot read property '%1' of %2").arg(name->toQString()).arg(object.toQStringNoThrow());
+ return engine->throwTypeError(message);
}
- o = RuntimeHelpers::convertToObject(ctx, object);
+ o = RuntimeHelpers::convertToObject(scope.engine, object);
if (!o) // type error
return Encode::undefined();
return o->get(name);
}
-ReturnedValue Runtime::getActivationProperty(ExecutionContext *ctx, String *name)
+ReturnedValue Runtime::getActivationProperty(ExecutionEngine *engine, int nameIndex)
{
+ Scope scope(engine);
+ ScopedString name(scope, engine->currentContext()->compilationUnit->runtimeStrings[nameIndex]);
+ ScopedContext ctx(scope, engine->currentContext());
return ctx->getProperty(name);
}
#endif // V4_BOOTSTRAP
-uint RuntimeHelpers::equalHelper(const ValueRef x, const ValueRef y)
+uint RuntimeHelpers::equalHelper(const Value &x, const Value &y)
{
- Q_ASSERT(x->type() != y->type() || (x->isManaged() && (x->isString() != y->isString())));
+ Q_ASSERT(x.type() != y.type() || (x.isManaged() && (x.isString() != y.isString())));
- if (x->isNumber() && y->isNumber())
- return x->asDouble() == y->asDouble();
- if (x->isNull() && y->isUndefined()) {
+ if (x.isNumber() && y.isNumber())
+ return x.asDouble() == y.asDouble();
+ if (x.isNull() && y.isUndefined()) {
return true;
- } else if (x->isUndefined() && y->isNull()) {
+ } else if (x.isUndefined() && y.isNull()) {
return true;
- } else if (x->isNumber() && y->isString()) {
+ } else if (x.isNumber() && y.isString()) {
double dy = RuntimeHelpers::toNumber(y);
- return x->asDouble() == dy;
- } else if (x->isString() && y->isNumber()) {
+ return x.asDouble() == dy;
+ } else if (x.isString() && y.isNumber()) {
double dx = RuntimeHelpers::toNumber(x);
- return dx == y->asDouble();
- } else if (x->isBoolean()) {
- return Runtime::compareEqual(Primitive::fromDouble((double) x->booleanValue()), y);
- } else if (y->isBoolean()) {
- return Runtime::compareEqual(x, Primitive::fromDouble((double) y->booleanValue()));
+ return dx == y.asDouble();
+ } else if (x.isBoolean()) {
+ return Runtime::compareEqual(Primitive::fromDouble((double) x.booleanValue()), y);
+ } else if (y.isBoolean()) {
+ return Runtime::compareEqual(x, Primitive::fromDouble((double) y.booleanValue()));
} else {
#ifdef V4_BOOTSTRAP
Q_UNIMPLEMENTED();
#else
- if ((x->isNumber() || x->isString()) && y->isObject()) {
- Scope scope(y->objectValue()->engine());
+ if ((x.isNumber() || x.isString()) && y.isObject()) {
+ Scope scope(y.objectValue()->engine());
ScopedValue py(scope, RuntimeHelpers::toPrimitive(y, PREFERREDTYPE_HINT));
return Runtime::compareEqual(x, py);
- } else if (x->isObject() && (y->isNumber() || y->isString())) {
- Scope scope(x->objectValue()->engine());
+ } else if (x.isObject() && (y.isNumber() || y.isString())) {
+ Scope scope(x.objectValue()->engine());
ScopedValue px(scope, RuntimeHelpers::toPrimitive(x, PREFERREDTYPE_HINT));
return Runtime::compareEqual(px, y);
}
@@ -710,42 +731,42 @@ uint RuntimeHelpers::equalHelper(const ValueRef x, const ValueRef y)
return false;
}
-Bool RuntimeHelpers::strictEqual(const ValueRef x, const ValueRef y)
+Bool RuntimeHelpers::strictEqual(const Value &x, const Value &y)
{
TRACE2(x, y);
- if (x->rawValue() == y->rawValue())
+ if (x.rawValue() == y.rawValue())
// NaN != NaN
- return !x->isNaN();
+ return !x.isNaN();
- if (x->isNumber())
- return y->isNumber() && x->asDouble() == y->asDouble();
- if (x->isManaged())
- return y->isManaged() && x->managed()->isEqualTo(y->managed());
+ if (x.isNumber())
+ return y.isNumber() && x.asDouble() == y.asDouble();
+ if (x.isManaged())
+ return y.isManaged() && x.cast<Managed>()->isEqualTo(y.cast<Managed>());
return false;
}
-QV4::Bool Runtime::compareGreaterThan(const QV4::ValueRef l, const QV4::ValueRef r)
+QV4::Bool Runtime::compareGreaterThan(const Value &l, const Value &r)
{
TRACE2(l, r);
- if (l->isInteger() && r->isInteger())
- return l->integerValue() > r->integerValue();
- if (l->isNumber() && r->isNumber())
- return l->asDouble() > r->asDouble();
- if (l->isString() && r->isString()) {
+ if (l.isInteger() && r.isInteger())
+ return l.integerValue() > r.integerValue();
+ if (l.isNumber() && r.isNumber())
+ return l.asDouble() > r.asDouble();
+ if (l.isString() && r.isString()) {
#ifdef V4_BOOTSTRAP
Q_UNIMPLEMENTED();
return false;
#else
- return r->stringValue()->compare(l->stringValue());
+ return r.stringValue()->compare(l.stringValue());
#endif
}
- if (l->isObject() || r->isObject()) {
+ if (l.isObject() || r.isObject()) {
#ifdef V4_BOOTSTRAP
Q_UNIMPLEMENTED();
#else
- QV4::ExecutionEngine *e = (l->isObject() ? l->objectValue() : r->objectValue())->engine();
+ QV4::ExecutionEngine *e = (l.isObject() ? l.objectValue() : r.objectValue())->engine();
QV4::Scope scope(e);
QV4::ScopedValue pl(scope, RuntimeHelpers::toPrimitive(l, QV4::NUMBER_HINT));
QV4::ScopedValue pr(scope, RuntimeHelpers::toPrimitive(r, QV4::NUMBER_HINT));
@@ -758,27 +779,27 @@ QV4::Bool Runtime::compareGreaterThan(const QV4::ValueRef l, const QV4::ValueRef
return dl > dr;
}
-QV4::Bool Runtime::compareLessThan(const QV4::ValueRef l, const QV4::ValueRef r)
+QV4::Bool Runtime::compareLessThan(const Value &l, const Value &r)
{
TRACE2(l, r);
- if (l->isInteger() && r->isInteger())
- return l->integerValue() < r->integerValue();
- if (l->isNumber() && r->isNumber())
- return l->asDouble() < r->asDouble();
- if (l->isString() && r->isString()) {
+ if (l.isInteger() && r.isInteger())
+ return l.integerValue() < r.integerValue();
+ if (l.isNumber() && r.isNumber())
+ return l.asDouble() < r.asDouble();
+ if (l.isString() && r.isString()) {
#ifdef V4_BOOTSTRAP
Q_UNIMPLEMENTED();
return false;
#else
- return l->stringValue()->compare(r->stringValue());
+ return l.stringValue()->compare(r.stringValue());
#endif
}
- if (l->isObject() || r->isObject()) {
+ if (l.isObject() || r.isObject()) {
#ifdef V4_BOOTSTRAP
Q_UNIMPLEMENTED();
#else
- QV4::ExecutionEngine *e = (l->isObject() ? l->objectValue() : r->objectValue())->engine();
+ QV4::ExecutionEngine *e = (l.isObject() ? l.objectValue() : r.objectValue())->engine();
QV4::Scope scope(e);
QV4::ScopedValue pl(scope, RuntimeHelpers::toPrimitive(l, QV4::NUMBER_HINT));
QV4::ScopedValue pr(scope, RuntimeHelpers::toPrimitive(r, QV4::NUMBER_HINT));
@@ -791,27 +812,27 @@ QV4::Bool Runtime::compareLessThan(const QV4::ValueRef l, const QV4::ValueRef r)
return dl < dr;
}
-QV4::Bool Runtime::compareGreaterEqual(const QV4::ValueRef l, const QV4::ValueRef r)
+QV4::Bool Runtime::compareGreaterEqual(const Value &l, const Value &r)
{
TRACE2(l, r);
- if (l->isInteger() && r->isInteger())
- return l->integerValue() >= r->integerValue();
- if (l->isNumber() && r->isNumber())
- return l->asDouble() >= r->asDouble();
- if (l->isString() && r->isString()) {
+ if (l.isInteger() && r.isInteger())
+ return l.integerValue() >= r.integerValue();
+ if (l.isNumber() && r.isNumber())
+ return l.asDouble() >= r.asDouble();
+ if (l.isString() && r.isString()) {
#ifdef V4_BOOTSTRAP
Q_UNIMPLEMENTED();
return false;
#else
- return !l->stringValue()->compare(r->stringValue());
+ return !l.stringValue()->compare(r.stringValue());
#endif
}
- if (l->isObject() || r->isObject()) {
+ if (l.isObject() || r.isObject()) {
#ifdef V4_BOOTSTRAP
Q_UNIMPLEMENTED();
#else
- QV4::ExecutionEngine *e = (l->isObject() ? l->objectValue() : r->objectValue())->engine();
+ QV4::ExecutionEngine *e = (l.isObject() ? l.objectValue() : r.objectValue())->engine();
QV4::Scope scope(e);
QV4::ScopedValue pl(scope, RuntimeHelpers::toPrimitive(l, QV4::NUMBER_HINT));
QV4::ScopedValue pr(scope, RuntimeHelpers::toPrimitive(r, QV4::NUMBER_HINT));
@@ -824,27 +845,27 @@ QV4::Bool Runtime::compareGreaterEqual(const QV4::ValueRef l, const QV4::ValueRe
return dl >= dr;
}
-QV4::Bool Runtime::compareLessEqual(const QV4::ValueRef l, const QV4::ValueRef r)
+QV4::Bool Runtime::compareLessEqual(const Value &l, const Value &r)
{
TRACE2(l, r);
- if (l->isInteger() && r->isInteger())
- return l->integerValue() <= r->integerValue();
- if (l->isNumber() && r->isNumber())
- return l->asDouble() <= r->asDouble();
- if (l->isString() && r->isString()) {
+ if (l.isInteger() && r.isInteger())
+ return l.integerValue() <= r.integerValue();
+ if (l.isNumber() && r.isNumber())
+ return l.asDouble() <= r.asDouble();
+ if (l.isString() && r.isString()) {
#ifdef V4_BOOTSTRAP
Q_UNIMPLEMENTED();
return false;
#else
- return !r->stringValue()->compare(l->stringValue());
+ return !r.stringValue()->compare(l.stringValue());
#endif
}
- if (l->isObject() || r->isObject()) {
+ if (l.isObject() || r.isObject()) {
#ifdef V4_BOOTSTRAP
Q_UNIMPLEMENTED();
#else
- QV4::ExecutionEngine *e = (l->isObject() ? l->objectValue() : r->objectValue())->engine();
+ QV4::ExecutionEngine *e = (l.isObject() ? l.objectValue() : r.objectValue())->engine();
QV4::Scope scope(e);
QV4::ScopedValue pl(scope, RuntimeHelpers::toPrimitive(l, QV4::NUMBER_HINT));
QV4::ScopedValue pr(scope, RuntimeHelpers::toPrimitive(r, QV4::NUMBER_HINT));
@@ -858,30 +879,52 @@ QV4::Bool Runtime::compareLessEqual(const QV4::ValueRef l, const QV4::ValueRef r
}
#ifndef V4_BOOTSTRAP
-ReturnedValue Runtime::callGlobalLookup(ExecutionContext *context, uint index, CallData *callData)
+Bool Runtime::compareInstanceof(ExecutionEngine *engine, const Value &left, const Value &right)
{
- Scope scope(context);
+ TRACE2(left, right);
+
+ Scope scope(engine);
+ ScopedValue v(scope, Runtime::instanceof(engine, left, right));
+ return v->booleanValue();
+}
+
+uint Runtime::compareIn(ExecutionEngine *engine, const Value &left, const Value &right)
+{
+ TRACE2(left, right);
+
+ Scope scope(engine);
+ ScopedValue v(scope, Runtime::in(engine, left, right));
+ return v->booleanValue();
+}
+
+
+ReturnedValue Runtime::callGlobalLookup(ExecutionEngine *engine, uint index, CallData *callData)
+{
+ Scope scope(engine);
Q_ASSERT(callData->thisObject.isUndefined());
- Lookup *l = context->d()->lookups + index;
- Scoped<FunctionObject> o(scope, l->globalGetter(l, context));
+ Lookup *l = engine->currentContext()->lookups + index;
+ ScopedFunctionObject o(scope, l->globalGetter(l, engine));
if (!o)
- return context->throwTypeError();
+ return engine->throwTypeError();
- if (o.getPointer() == scope.engine->evalFunction && l->name->equals(scope.engine->id_eval))
+ ScopedString name(scope, engine->currentContext()->compilationUnit->runtimeStrings[l->nameIndex]);
+ if (o->d() == scope.engine->evalFunction && name->equals(scope.engine->id_eval))
return static_cast<EvalFunction *>(o.getPointer())->evalCall(callData, true);
return o->call(callData);
}
-ReturnedValue Runtime::callActivationProperty(ExecutionContext *context, String *name, CallData *callData)
+ReturnedValue Runtime::callActivationProperty(ExecutionEngine *engine, int nameIndex, CallData *callData)
{
Q_ASSERT(callData->thisObject.isUndefined());
- Scope scope(context);
+ Scope scope(engine);
+ ScopedString name(scope, engine->currentContext()->compilationUnit->runtimeStrings[nameIndex]);
ScopedObject base(scope);
- ScopedValue func(scope, context->getPropertyAndBase(name, base.ptr->o));
+ ScopedContext ctx(scope, engine->currentContext());
+ ScopedValue func(scope, ctx->getPropertyAndBase(name, base.getRef()));
if (scope.engine->hasException)
return Encode::undefined();
@@ -894,242 +937,255 @@ ReturnedValue Runtime::callActivationProperty(ExecutionContext *context, String
if (base)
objectAsString = ScopedValue(scope, base.asReturnedValue())->toQStringNoThrow();
QString msg = QStringLiteral("Property '%1' of object %2 is not a function").arg(name->toQString()).arg(objectAsString);
- return context->throwTypeError(msg);
+ return engine->throwTypeError(msg);
}
- if (o == scope.engine->evalFunction && name->equals(scope.engine->id_eval)) {
+ if (o->d() == scope.engine->evalFunction && name->equals(scope.engine->id_eval)) {
return static_cast<EvalFunction *>(o)->evalCall(callData, true);
}
return o->call(callData);
}
-ReturnedValue Runtime::callProperty(ExecutionContext *context, String *name, CallData *callData)
+ReturnedValue Runtime::callProperty(ExecutionEngine *engine, int nameIndex, CallData *callData)
{
- Scope scope(context);
- Scoped<Object> baseObject(scope, callData->thisObject);
+ Scope scope(engine);
+ ScopedString name(scope, engine->currentContext()->compilationUnit->runtimeStrings[nameIndex]);
+ ScopedObject baseObject(scope, callData->thisObject);
if (!baseObject) {
Q_ASSERT(!callData->thisObject.isEmpty());
if (callData->thisObject.isNullOrUndefined()) {
QString message = QStringLiteral("Cannot call method '%1' of %2").arg(name->toQString()).arg(callData->thisObject.toQStringNoThrow());
- return context->throwTypeError(message);
+ return engine->throwTypeError(message);
}
- baseObject = RuntimeHelpers::convertToObject(context, ValueRef(&callData->thisObject));
+ baseObject = RuntimeHelpers::convertToObject(scope.engine, callData->thisObject);
if (!baseObject) // type error
return Encode::undefined();
callData->thisObject = baseObject.asReturnedValue();
}
- Scoped<FunctionObject> o(scope, baseObject->get(name));
+ ScopedFunctionObject o(scope, baseObject->get(name));
if (!o) {
QString error = QStringLiteral("Property '%1' of object %2 is not a function").arg(name->toQString(), callData->thisObject.toQStringNoThrow());
- return context->throwTypeError(error);
+ return engine->throwTypeError(error);
}
return o->call(callData);
}
-ReturnedValue Runtime::callPropertyLookup(ExecutionContext *context, uint index, CallData *callData)
+ReturnedValue Runtime::callPropertyLookup(ExecutionEngine *engine, uint index, CallData *callData)
{
- Lookup *l = context->d()->lookups + index;
+ Lookup *l = engine->currentContext()->lookups + index;
Value v;
- v = l->getter(l, callData->thisObject);
+ v = l->getter(l, engine, callData->thisObject);
if (!v.isObject())
- return context->throwTypeError();
+ return engine->throwTypeError();
return v.objectValue()->call(callData);
}
-ReturnedValue Runtime::callElement(ExecutionContext *context, const ValueRef index, CallData *callData)
+ReturnedValue Runtime::callElement(ExecutionEngine *engine, const Value &index, CallData *callData)
{
- Scope scope(context);
- ScopedObject baseObject(scope, callData->thisObject.toObject(context));
- ScopedString s(scope, index->toString(context));
+ Scope scope(engine);
+ ScopedObject baseObject(scope, callData->thisObject.toObject(engine));
+ ScopedString s(scope, index.toString(engine));
if (scope.engine->hasException)
return Encode::undefined();
callData->thisObject = baseObject;
- ScopedObject o(scope, baseObject->get(s.getPointer()));
+ ScopedObject o(scope, baseObject->get(s));
if (!o)
- return context->throwTypeError();
+ return engine->throwTypeError();
return o->call(callData);
}
-ReturnedValue Runtime::callValue(ExecutionContext *context, const ValueRef func, CallData *callData)
+ReturnedValue Runtime::callValue(ExecutionEngine *engine, const Value &func, CallData *callData)
{
- if (!func->isObject())
- return context->throwTypeError(QStringLiteral("%1 is not a function").arg(func->toQStringNoThrow()));
+ if (!func.isObject())
+ return engine->throwTypeError(QStringLiteral("%1 is not a function").arg(func.toQStringNoThrow()));
- return func->objectValue()->call(callData);
+ return func.objectValue()->call(callData);
}
-ReturnedValue Runtime::constructGlobalLookup(ExecutionContext *context, uint index, CallData *callData)
+ReturnedValue Runtime::constructGlobalLookup(ExecutionEngine *engine, uint index, CallData *callData)
{
- Scope scope(context);
+ Scope scope(engine);
Q_ASSERT(callData->thisObject.isUndefined());
- Lookup *l = context->d()->lookups + index;
- Scoped<Object> f(scope, l->globalGetter(l, context));
+ Lookup *l = engine->currentContext()->lookups + index;
+ ScopedObject f(scope, l->globalGetter(l, engine));
if (!f)
- return context->throwTypeError();
+ return engine->throwTypeError();
return f->construct(callData);
}
-ReturnedValue Runtime::constructActivationProperty(ExecutionContext *context, String *name, CallData *callData)
+ReturnedValue Runtime::constructActivationProperty(ExecutionEngine *engine, int nameIndex, CallData *callData)
{
- Scope scope(context);
- ScopedValue func(scope, context->getProperty(name));
+ Scope scope(engine);
+ ScopedContext ctx(scope, engine->currentContext());
+ ScopedString name(scope, engine->currentContext()->compilationUnit->runtimeStrings[nameIndex]);
+ ScopedValue func(scope, ctx->getProperty(name));
if (scope.engine->hasException)
return Encode::undefined();
Object *f = func->asObject();
if (!f)
- return context->throwTypeError();
+ return engine->throwTypeError();
return f->construct(callData);
}
-ReturnedValue Runtime::constructValue(ExecutionContext *context, const ValueRef func, CallData *callData)
+ReturnedValue Runtime::constructValue(ExecutionEngine *engine, const Value &func, CallData *callData)
{
- Object *f = func->asObject();
+ Object *f = func.asObject();
if (!f)
- return context->throwTypeError();
+ return engine->throwTypeError();
return f->construct(callData);
}
-ReturnedValue Runtime::constructProperty(ExecutionContext *context, String *name, CallData *callData)
+ReturnedValue Runtime::constructProperty(ExecutionEngine *engine, int nameIndex, CallData *callData)
{
- Scope scope(context);
- ScopedObject thisObject(scope, callData->thisObject.toObject(context));
+ Scope scope(engine);
+ ScopedObject thisObject(scope, callData->thisObject.toObject(engine));
+ ScopedString name(scope, engine->currentContext()->compilationUnit->runtimeStrings[nameIndex]);
if (scope.engine->hasException)
return Encode::undefined();
- Scoped<Object> f(scope, thisObject->get(name));
+ ScopedObject f(scope, thisObject->get(name));
if (!f)
- return context->throwTypeError();
+ return engine->throwTypeError();
return f->construct(callData);
}
-ReturnedValue Runtime::constructPropertyLookup(ExecutionContext *context, uint index, CallData *callData)
+ReturnedValue Runtime::constructPropertyLookup(ExecutionEngine *engine, uint index, CallData *callData)
{
- Lookup *l = context->d()->lookups + index;
+ Lookup *l = engine->currentContext()->lookups + index;
Value v;
- v = l->getter(l, callData->thisObject);
+ v = l->getter(l, engine, callData->thisObject);
if (!v.isObject())
- return context->throwTypeError();
+ return engine->throwTypeError();
return v.objectValue()->construct(callData);
}
-void Runtime::throwException(ExecutionContext *context, const ValueRef value)
+void Runtime::throwException(ExecutionEngine *engine, const Value &value)
{
- if (!value->isEmpty())
- context->throwError(value);
+ if (!value.isEmpty())
+ engine->throwError(value);
}
-ReturnedValue Runtime::typeofValue(ExecutionContext *ctx, const ValueRef value)
+ReturnedValue Runtime::typeofValue(ExecutionEngine *engine, const Value &value)
{
- Scope scope(ctx);
+ Scope scope(engine);
ScopedString res(scope);
- switch (value->type()) {
+ switch (value.type()) {
case Value::Undefined_Type:
- res = ctx->engine()->id_undefined;
+ res = engine->id_undefined;
break;
case Value::Null_Type:
- res = ctx->engine()->id_object;
+ res = engine->id_object;
break;
case Value::Boolean_Type:
- res = ctx->engine()->id_boolean;
+ res = engine->id_boolean;
break;
case Value::Managed_Type:
- if (value->isString())
- res = ctx->engine()->id_string;
- else if (value->objectValue()->asFunctionObject())
- res = ctx->engine()->id_function;
+ if (value.isString())
+ res = engine->id_string;
+ else if (value.objectValue()->asFunctionObject())
+ res = engine->id_function;
else
- res = ctx->engine()->id_object; // ### implementation-defined
+ res = engine->id_object; // ### implementation-defined
break;
default:
- res = ctx->engine()->id_number;
+ res = engine->id_number;
break;
}
return res.asReturnedValue();
}
-QV4::ReturnedValue Runtime::typeofName(ExecutionContext *context, String *name)
+QV4::ReturnedValue Runtime::typeofName(ExecutionEngine *engine, int nameIndex)
{
- Scope scope(context);
- ScopedValue prop(scope, context->getProperty(name));
+ Scope scope(engine);
+ ScopedString name(scope, engine->currentContext()->compilationUnit->runtimeStrings[nameIndex]);
+ ScopedContext ctx(scope, engine->currentContext());
+ ScopedValue prop(scope, ctx->getProperty(name));
// typeof doesn't throw. clear any possible exception
scope.engine->hasException = false;
- return Runtime::typeofValue(context, prop);
+ return Runtime::typeofValue(engine, prop);
}
-QV4::ReturnedValue Runtime::typeofMember(ExecutionContext *context, const ValueRef base, String *name)
+QV4::ReturnedValue Runtime::typeofMember(ExecutionEngine *engine, const Value &base, int nameIndex)
{
- Scope scope(context);
- ScopedObject obj(scope, base->toObject(context));
+ Scope scope(engine);
+ ScopedString name(scope, engine->currentContext()->compilationUnit->runtimeStrings[nameIndex]);
+ ScopedObject obj(scope, base.toObject(engine));
if (scope.engine->hasException)
return Encode::undefined();
ScopedValue prop(scope, obj->get(name));
- return Runtime::typeofValue(context, prop);
+ return Runtime::typeofValue(engine, prop);
}
-QV4::ReturnedValue Runtime::typeofElement(ExecutionContext *context, const ValueRef base, const ValueRef index)
+QV4::ReturnedValue Runtime::typeofElement(ExecutionEngine *engine, const Value &base, const Value &index)
{
- Scope scope(context);
- ScopedString name(scope, index->toString(context));
- ScopedObject obj(scope, base->toObject(context));
+ Scope scope(engine);
+ ScopedString name(scope, index.toString(engine));
+ ScopedObject obj(scope, base.toObject(engine));
if (scope.engine->hasException)
return Encode::undefined();
- ScopedValue prop(scope, obj->get(name.getPointer()));
- return Runtime::typeofValue(context, prop);
+ ScopedValue prop(scope, obj->get(name));
+ return Runtime::typeofValue(engine, prop);
}
-ExecutionContext *Runtime::pushWithScope(const ValueRef o, ExecutionContext *ctx)
+void Runtime::pushWithScope(const Value &o, ExecutionEngine *engine)
{
- Scope scope(ctx);
- ScopedObject obj(scope, o->toObject(ctx));
- return reinterpret_cast<ExecutionContext *>(ctx->newWithContext(obj));
+ Scope scope(engine);
+ ScopedObject obj(scope, o.toObject(engine));
+ ScopedContext ctx(scope, engine->currentContext());
+ ctx->newWithContext(obj);
}
-ReturnedValue Runtime::unwindException(ExecutionContext *ctx)
+ReturnedValue Runtime::unwindException(ExecutionEngine *engine)
{
- if (!ctx->engine()->hasException)
+ if (!engine->hasException)
return Primitive::emptyValue().asReturnedValue();
- return ctx->engine()->catchException(ctx, 0);
+ return engine->catchException(0);
}
-ExecutionContext *Runtime::pushCatchScope(ExecutionContext *ctx, String *exceptionVarName)
+void Runtime::pushCatchScope(NoThrowEngine *engine, int exceptionVarNameIndex)
{
- Scope scope(ctx);
- ScopedValue v(scope, ctx->engine()->catchException(ctx, 0));
- return reinterpret_cast<ExecutionContext *>(ctx->newCatchContext(exceptionVarName, v));
+ Scope scope(engine);
+ ScopedValue v(scope, engine->catchException(0));
+ ScopedString exceptionVarName(scope, engine->currentContext()->compilationUnit->runtimeStrings[exceptionVarNameIndex]);
+ ScopedContext ctx(scope, engine->currentContext());
+ ctx->newCatchContext(exceptionVarName, v);
}
-ExecutionContext *Runtime::popScope(ExecutionContext *ctx)
+void Runtime::popScope(ExecutionEngine *engine)
{
- return ctx->engine()->popContext();
+ engine->popContext();
}
-void Runtime::declareVar(ExecutionContext *ctx, bool deletable, String *name)
+void Runtime::declareVar(ExecutionEngine *engine, bool deletable, int nameIndex)
{
+ Scope scope(engine);
+ ScopedString name(scope, engine->currentContext()->compilationUnit->runtimeStrings[nameIndex]);
+ ScopedContext ctx(scope, engine->currentContext());
ctx->createMutableBinding(name, deletable);
}
-ReturnedValue Runtime::arrayLiteral(ExecutionContext *ctx, Value *values, uint length)
+ReturnedValue Runtime::arrayLiteral(ExecutionEngine *engine, Value *values, uint length)
{
- Scope scope(ctx);
- Scoped<ArrayObject> a(scope, ctx->engine()->newArrayObject());
+ Scope scope(engine);
+ ScopedArrayObject a(scope, engine->newArrayObject());
if (length) {
a->arrayReserve(length);
@@ -1139,11 +1195,11 @@ ReturnedValue Runtime::arrayLiteral(ExecutionContext *ctx, Value *values, uint l
return a.asReturnedValue();
}
-ReturnedValue Runtime::objectLiteral(QV4::ExecutionContext *ctx, const QV4::Value *args, int classId, int arrayValueCount, int arrayGetterSetterCountAndFlags)
+ReturnedValue Runtime::objectLiteral(ExecutionEngine *engine, const QV4::Value *args, int classId, int arrayValueCount, int arrayGetterSetterCountAndFlags)
{
- Scope scope(ctx);
- QV4::InternalClass *klass = ctx->d()->compilationUnit->runtimeClasses[classId];
- Scoped<Object> o(scope, ctx->engine()->newObject(klass));
+ Scope scope(engine);
+ QV4::InternalClass *klass = engine->currentContext()->compilationUnit->runtimeClasses[classId];
+ ScopedObject o(scope, engine->newObject(klass, engine->objectPrototype.asObject()));
{
bool needSparseArray = arrayGetterSetterCountAndFlags >> 30;
@@ -1152,7 +1208,7 @@ ReturnedValue Runtime::objectLiteral(QV4::ExecutionContext *ctx, const QV4::Valu
}
for (uint i = 0; i < klass->size; ++i)
- o->memberData()[i] = *args++;
+ o->memberData()->data[i] = *args++;
if (arrayValueCount > 0) {
ScopedValue entry(scope);
@@ -1181,54 +1237,55 @@ ReturnedValue Runtime::objectLiteral(QV4::ExecutionContext *ctx, const QV4::Valu
return o.asReturnedValue();
}
-QV4::ReturnedValue Runtime::setupArgumentsObject(ExecutionContext *ctx)
+QV4::ReturnedValue Runtime::setupArgumentsObject(ExecutionEngine *engine)
{
- Q_ASSERT(ctx->d()->type >= ExecutionContext::Type_CallContext);
- CallContext *c = static_cast<CallContext *>(ctx);
- return (c->engine()->memoryManager->alloc<ArgumentsObject>(c))->asReturnedValue();
+ Q_ASSERT(engine->currentContext()->type >= Heap::ExecutionContext::Type_CallContext);
+ Scope scope(engine);
+ Scoped<CallContext> c(scope, static_cast<Heap::CallContext *>(engine->currentContext()));
+ return (engine->memoryManager->alloc<ArgumentsObject>(c))->asReturnedValue();
}
#endif // V4_BOOTSTRAP
-QV4::ReturnedValue Runtime::increment(const QV4::ValueRef value)
+QV4::ReturnedValue Runtime::increment(const Value &value)
{
TRACE1(value);
- if (value->isInteger() && value->integerValue() < INT_MAX)
- return Encode(value->integerValue() + 1);
+ if (value.isInteger() && value.integerValue() < INT_MAX)
+ return Encode(value.integerValue() + 1);
else {
- double d = value->toNumber();
+ double d = value.toNumber();
return Encode(d + 1.);
}
}
-QV4::ReturnedValue Runtime::decrement(const QV4::ValueRef value)
+QV4::ReturnedValue Runtime::decrement(const Value &value)
{
TRACE1(value);
- if (value->isInteger() && value->integerValue() > INT_MIN)
- return Encode(value->integerValue() - 1);
+ if (value.isInteger() && value.integerValue() > INT_MIN)
+ return Encode(value.integerValue() - 1);
else {
- double d = value->toNumber();
+ double d = value.toNumber();
return Encode(d - 1.);
}
}
#ifndef V4_BOOTSTRAP
-QV4::ReturnedValue RuntimeHelpers::toString(QV4::ExecutionContext *ctx, const QV4::ValueRef value)
+QV4::ReturnedValue RuntimeHelpers::toString(ExecutionEngine *engine, const Value &value)
{
- if (value->isString())
+ if (value.isString())
return value.asReturnedValue();
- return RuntimeHelpers::convertToString(ctx, value)->asReturnedValue();
+ return RuntimeHelpers::convertToString(engine, value)->asReturnedValue();
}
-QV4::ReturnedValue RuntimeHelpers::toObject(QV4::ExecutionContext *ctx, const QV4::ValueRef value)
+QV4::ReturnedValue RuntimeHelpers::toObject(ExecutionEngine *engine, const Value &value)
{
- if (value->isObject())
+ if (value.isObject())
return value.asReturnedValue();
- Returned<Object> *o = RuntimeHelpers::convertToObject(ctx, value);
+ Heap::Object *o = RuntimeHelpers::convertToObject(engine, value);
if (!o) // type error
return Encode::undefined();
@@ -1237,16 +1294,16 @@ QV4::ReturnedValue RuntimeHelpers::toObject(QV4::ExecutionContext *ctx, const QV
#endif // V4_BOOTSTRAP
-ReturnedValue Runtime::toDouble(const ValueRef value)
+ReturnedValue Runtime::toDouble(const Value &value)
{
TRACE1(value);
- return Encode(value->toNumber());
+ return Encode(value.toNumber());
}
-int Runtime::toInt(const ValueRef value)
+int Runtime::toInt(const Value &value)
{
TRACE1(value);
- return value->toInt32();
+ return value.toInt32();
}
int Runtime::doubleToInt(const double &d)
@@ -1255,10 +1312,10 @@ int Runtime::doubleToInt(const double &d)
return Primitive::toInt32(d);
}
-unsigned Runtime::toUInt(const ValueRef value)
+unsigned Runtime::toUInt(const Value &value)
{
TRACE1(value);
- return value->toUInt32();
+ return value.toUInt32();
}
unsigned Runtime::doubleToUInt(const double &d)
@@ -1269,99 +1326,108 @@ unsigned Runtime::doubleToUInt(const double &d)
#ifndef V4_BOOTSTRAP
-ReturnedValue Runtime::regexpLiteral(ExecutionContext *ctx, int id)
+ReturnedValue Runtime::regexpLiteral(ExecutionEngine *engine, int id)
{
- return ctx->d()->compilationUnit->runtimeRegularExpressions[id].asReturnedValue();
+ return engine->currentContext()->compilationUnit->runtimeRegularExpressions[id].asReturnedValue();
}
-ReturnedValue Runtime::getQmlIdArray(NoThrowContext *ctx)
+ReturnedValue Runtime::getQmlIdArray(NoThrowEngine *engine)
{
- Q_ASSERT(ctx->engine()->qmlContextObject()->getPointer()->as<QmlContextWrapper>());
- return static_cast<QmlContextWrapper *>(ctx->engine()->qmlContextObject()->getPointer())->idObjectsArray();
+ Q_ASSERT(engine->qmlContextObject());
+ Scope scope(engine);
+ Scoped<QmlContextWrapper> wrapper(scope, engine->qmlContextObject());
+ return wrapper->idObjectsArray();
}
-ReturnedValue Runtime::getQmlContextObject(NoThrowContext *ctx)
+ReturnedValue Runtime::getQmlContextObject(NoThrowEngine *engine)
{
- QQmlContextData *context = QmlContextWrapper::callingContext(ctx->engine());
+ QQmlContextData *context = QmlContextWrapper::callingContext(engine);
if (!context)
return Encode::undefined();
- return QObjectWrapper::wrap(ctx->d()->engine, context->contextObject);
+ return QObjectWrapper::wrap(engine, context->contextObject);
}
-ReturnedValue Runtime::getQmlScopeObject(NoThrowContext *ctx)
+ReturnedValue Runtime::getQmlScopeObject(NoThrowEngine *engine)
{
- Scope scope(ctx);
- QV4::Scoped<QmlContextWrapper> c(scope, ctx->engine()->qmlContextObject(), Scoped<QmlContextWrapper>::Cast);
- return QObjectWrapper::wrap(ctx->d()->engine, c->getScopeObject());
+ Scope scope(engine);
+ QV4::Scoped<QmlContextWrapper> c(scope, engine->qmlContextObject());
+ return QObjectWrapper::wrap(engine, c->getScopeObject());
}
-ReturnedValue Runtime::getQmlQObjectProperty(ExecutionContext *ctx, const ValueRef object, int propertyIndex, bool captureRequired)
+ReturnedValue Runtime::getQmlQObjectProperty(ExecutionEngine *engine, const Value &object, int propertyIndex, bool captureRequired)
{
- Scope scope(ctx);
+ Scope scope(engine);
QV4::Scoped<QObjectWrapper> wrapper(scope, object);
if (!wrapper) {
- ctx->throwTypeError(QStringLiteral("Cannot read property of null"));
+ engine->throwTypeError(QStringLiteral("Cannot read property of null"));
return Encode::undefined();
}
+ ScopedContext ctx(scope, engine->currentContext());
return QV4::QObjectWrapper::getProperty(wrapper->object(), ctx, propertyIndex, captureRequired);
}
-QV4::ReturnedValue Runtime::getQmlAttachedProperty(ExecutionContext *ctx, int attachedPropertiesId, int propertyIndex)
+QV4::ReturnedValue Runtime::getQmlAttachedProperty(ExecutionEngine *engine, int attachedPropertiesId, int propertyIndex)
{
- Scope scope(ctx);
- QV4::Scoped<QmlContextWrapper> c(scope, ctx->engine()->qmlContextObject(), Scoped<QmlContextWrapper>::Cast);
+ Scope scope(engine);
+ QV4::Scoped<QmlContextWrapper> c(scope, engine->qmlContextObject());
QObject *scopeObject = c->getScopeObject();
QObject *attachedObject = qmlAttachedPropertiesObjectById(attachedPropertiesId, scopeObject);
- QQmlEngine *qmlEngine = ctx->engine()->v8Engine->engine();
- QQmlData::ensurePropertyCache(qmlEngine, attachedObject);
+ QJSEngine *jsEngine = engine->jsEngine();
+ QQmlData::ensurePropertyCache(jsEngine, attachedObject);
+ ScopedContext ctx(scope, engine->currentContext());
return QV4::QObjectWrapper::getProperty(attachedObject, ctx, propertyIndex, /*captureRequired*/true);
}
-ReturnedValue Runtime::getQmlSingletonQObjectProperty(ExecutionContext *ctx, const ValueRef object, int propertyIndex, bool captureRequired)
+ReturnedValue Runtime::getQmlSingletonQObjectProperty(ExecutionEngine *engine, const Value &object, int propertyIndex, bool captureRequired)
{
- Scope scope(ctx);
+ Scope scope(engine);
QV4::Scoped<QmlTypeWrapper> wrapper(scope, object);
if (!wrapper) {
- ctx->throwTypeError(QStringLiteral("Cannot read property of null"));
+ scope.engine->throwTypeError(QStringLiteral("Cannot read property of null"));
return Encode::undefined();
}
+ ScopedContext ctx(scope, engine->currentContext());
return QV4::QObjectWrapper::getProperty(wrapper->singletonObject(), ctx, propertyIndex, captureRequired);
}
-void Runtime::setQmlQObjectProperty(ExecutionContext *ctx, const ValueRef object, int propertyIndex, const ValueRef value)
+void Runtime::setQmlQObjectProperty(ExecutionEngine *engine, const Value &object, int propertyIndex, const Value &value)
{
- Scope scope(ctx);
+ Scope scope(engine);
QV4::Scoped<QObjectWrapper> wrapper(scope, object);
if (!wrapper) {
- ctx->throwTypeError(QStringLiteral("Cannot write property of null"));
+ engine->throwTypeError(QStringLiteral("Cannot write property of null"));
return;
}
+ ScopedContext ctx(scope, engine->currentContext());
wrapper->setProperty(ctx, propertyIndex, value);
}
-ReturnedValue Runtime::getQmlImportedScripts(NoThrowContext *ctx)
+ReturnedValue Runtime::getQmlImportedScripts(NoThrowEngine *engine)
{
- QQmlContextData *context = QmlContextWrapper::callingContext(ctx->engine());
+ QQmlContextData *context = QmlContextWrapper::callingContext(engine);
if (!context)
return Encode::undefined();
return context->importedScripts.value();
}
-QV4::ReturnedValue Runtime::getQmlSingleton(QV4::NoThrowContext *ctx, String *name)
+QV4::ReturnedValue Runtime::getQmlSingleton(QV4::NoThrowEngine *engine, int nameIndex)
{
- return static_cast<QmlContextWrapper *>(ctx->engine()->qmlContextObject()->getPointer())->qmlSingletonWrapper(ctx->engine()->v8Engine, name);
+ Scope scope(engine);
+ ScopedString name(scope, engine->currentContext()->compilationUnit->runtimeStrings[nameIndex]);
+ Scoped<QmlContextWrapper> wrapper(scope, engine->qmlContextObject());
+ return wrapper->qmlSingletonWrapper(engine, name);
}
-void Runtime::convertThisToObject(ExecutionContext *ctx)
+void Runtime::convertThisToObject(ExecutionEngine *engine)
{
- Value *t = &ctx->d()->callData->thisObject;
+ Value *t = &engine->currentContext()->callData->thisObject;
if (t->isObject())
return;
if (t->isNullOrUndefined()) {
- *t = ctx->engine()->globalObject->asReturnedValue();
+ *t = engine->globalObject()->asReturnedValue();
} else {
- *t = t->toObject(ctx)->asReturnedValue();
+ *t = t->toObject(engine)->asReturnedValue();
}
}