struct ExecutionEngine;
struct QObjectWrapper;
+// ReturnedValue is used to return values from runtime methods
+// the type has to be a primitive type (no struct or union), so that the compiler
+// will return it in a register on all platforms.
+// It will be returned in rax on x64, [eax,edx] on x86 and [r0,r1] on arm
+typedef quint64 ReturnedValue;
+
namespace Global {
enum {
ReservedArgumentCount = 6
else if (v < 1.e21)
str = QString::number(v, 'f', int (fdigits));
else
- return __qmljs_string_from_number(ctx, v).get();
+ return Value::fromReturnedValue(__qmljs_string_from_number(ctx, v));
return Value::fromString(ctx, str);
}
Value prec = ctx->argument(0);
if (prec.isUndefined())
- return __qmljs_to_string(v, ctx).get();
+ return Value::fromReturnedValue(__qmljs_to_string(v, ctx));
double precision = prec.toInt32();
if (precision < 1 || precision > 21) {
inline ExecutionEngine *engine() const { return internalClass->engine; }
+ ReturnedValue asReturnedValue() { return Value::fromObject(this).asReturnedValue(); }
+
// Array handling
uint allocArrayValue() {
obj->setPrototype(proto.objectValue());
return Value::fromObject(obj);
}
- return __qmljs_to_object(v4->current, ValueRef(&callData->args[0])).get();
+ return Value::fromReturnedValue(__qmljs_to_object(v4->current, ValueRef(&callData->args[0])));
}
Value ObjectCtor::call(Managed *m, CallData *callData)
{
if (!callData->argc || callData->args[0].isUndefined() || callData->args[0].isNull())
return Value::fromObject(m->engine()->newObject());
- return __qmljs_to_object(m->engine()->current, ValueRef(&callData->args[0])).get();
+ return Value::fromReturnedValue(__qmljs_to_object(m->engine()->current, ValueRef(&callData->args[0])));
}
void ObjectPrototype::init(ExecutionContext *ctx, const Value &ctor)
} else if (ctx->thisObject.isNull()) {
return Value::fromString(ctx, QStringLiteral("[object Null]"));
} else {
- Value obj = __qmljs_to_object(ctx, ValueRef(&ctx->thisObject)).get();
+ Value obj = Value::fromReturnedValue(__qmljs_to_object(ctx, ValueRef(&ctx->thisObject)));
QString className = obj.objectValue()->className();
return Value::fromString(ctx, QString::fromUtf8("[object %1]").arg(className));
}
{
QV4::Function *clos = ctx->compilationUnit->runtimeFunctions[functionId];
Q_ASSERT(clos);
- return Value::fromObject(FunctionObject::creatScriptFunction(ctx, clos));
+ return FunctionObject::creatScriptFunction(ctx, clos)->asReturnedValue();
}
ReturnedValue __qmljs_delete_subscript(ExecutionContext *ctx, const ValueRef base, const ValueRef index)
if (Object *o = base->asObject()) {
uint n = index->asArrayIndex();
if (n < UINT_MAX) {
- return Value::fromBoolean(o->deleteIndexedProperty(n));
+ return Value::fromBoolean(o->deleteIndexedProperty(n)).asReturnedValue();
}
}
ReturnedValue __qmljs_delete_member(ExecutionContext *ctx, const ValueRef base, String *name)
{
Object *obj = base->toObject(ctx);
- return Value::fromBoolean(obj->deleteProperty(name));
+ return Value::fromBoolean(obj->deleteProperty(name)).asReturnedValue();
}
ReturnedValue __qmljs_delete_name(ExecutionContext *ctx, String *name)
{
- return Value::fromBoolean(ctx->deleteProperty(name));
+ return Value::fromBoolean(ctx->deleteProperty(name)).asReturnedValue();
}
QV4::ReturnedValue __qmljs_add_helper(ExecutionContext *ctx, const ValueRef left, const ValueRef right)
if (!pright->isString())
pright = __qmljs_to_string(pright, ctx);
String *string = __qmljs_string_concat(ctx, pleft->stringValue(), pright->stringValue());
- return Value::fromString(string);
+ return Value::fromString(string).asReturnedValue();
}
double x = __qmljs_to_number(pleft);
double y = __qmljs_to_number(pright);
- return Value::fromDouble(x + y);
+ return Value::fromDouble(x + y).asReturnedValue();
}
QV4::ReturnedValue __qmljs_instanceof(ExecutionContext *ctx, const ValueRef left, const ValueRef right)
ctx->throwTypeError();
bool r = o->hasInstance(*left);
- return Value::fromBoolean(r);
+ return Value::fromBoolean(r).asReturnedValue();
}
QV4::ReturnedValue __qmljs_in(ExecutionContext *ctx, const ValueRef left, const ValueRef right)
ctx->throwTypeError();
String *s = left->toString(ctx);
bool r = right->objectValue()->__hasProperty__(s);
- return Value::fromBoolean(r);
+ return Value::fromBoolean(r).asReturnedValue();
}
static void inplaceBitOp(ExecutionContext *ctx, String *name, const ValueRef value, BinOp op)
QString qstr;
__qmljs_numberToString(&qstr, number, 10);
String *string = ctx->engine->newString(qstr);
- return Value::fromString(string);
+ return string->asReturnedValue();
}
String *__qmljs_string_concat(ExecutionContext *ctx, String *first, String *second)
callData->thisObject = Value::fromObject(object);
Value r = o->call(callData);
if (r.isPrimitive())
- return r;
+ return r.asReturnedValue();
}
conv = object->get(meth2);
callData->thisObject = Value::fromObject(object);
Value r = o->call(callData);
if (r.isPrimitive())
- return r;
+ return r.asReturnedValue();
}
ctx->throwTypeError();
- return Value::undefinedValue();
+ return Value::undefinedValue().asReturnedValue();
}
Bool __qmljs_to_boolean(const ValueRef value)
ScopedValue prim(scope, __qmljs_to_primitive(value, STRING_HINT));
return __qmljs_convert_to_string(ctx, prim);
}
- case Value::Integer_Type:
- return __qmljs_string_from_number(ctx, value->int_32).get().stringValue();
- default: // double
- return __qmljs_string_from_number(ctx, value->doubleValue()).get().stringValue();
+ case Value::Integer_Type: {
+ ValueScope scope(ctx);
+ ScopedValue dbl(scope, __qmljs_string_from_number(ctx, value->int_32));
+ return dbl->stringValue();
+ }
+ default: { // double
+ ValueScope scope(ctx);
+ ScopedValue dbl(scope, __qmljs_string_from_number(ctx, value->doubleValue()));
+ return dbl->stringValue();
+ }
} // switch
}
if (idx < UINT_MAX) {
if (String *str = object->asString()) {
if (idx >= (uint)str->toQString().length()) {
- return Value::undefinedValue();
+ return Value::undefinedValue().asReturnedValue();
}
const QString s = str->toQString().mid(idx, 1);
- return Value::fromString(ctx, s);
+ return Value::fromString(ctx, s).asReturnedValue();
}
}
uint pidx = o->propertyIndexFromArrayIndex(idx);
if (pidx < UINT_MAX) {
if (!o->arrayAttributes || o->arrayAttributes[pidx].isData()) {
- return o->arrayData[pidx].value;
+ return o->arrayData[pidx].value.asReturnedValue();
}
}
- return o->getIndexed(idx);
+ return o->getIndexed(idx).asReturnedValue();
}
String *name = index->toString(ctx);
- return o->get(name);
+ return o->get(name).asReturnedValue();
}
void __qmljs_set_element(ExecutionContext *ctx, const ValueRef object, const ValueRef index, const ValueRef value)
if (!in->isNullOrUndefined())
o = in->toObject(ctx);
Object *it = ctx->engine->newForEachIteratorObject(ctx, o);
- return Value::fromObject(it);
+ return Value::fromObject(it).asReturnedValue();
}
ReturnedValue __qmljs_foreach_next_property_name(const ValueRef foreach_iterator)
ForEachIteratorObject *it = static_cast<ForEachIteratorObject *>(foreach_iterator->objectValue());
Q_ASSERT(it->as<ForEachIteratorObject>());
- return it->nextPropertyName();
+ return it->nextPropertyName().asReturnedValue();
}
Value res;
Managed *m = object->asManaged();
if (m)
- return m->get(name);
+ return m->get(name).asReturnedValue();
if (object->isNullOrUndefined()) {
QString message = QStringLiteral("Cannot read property '%1' of %2").arg(name->toQString()).arg(object->toQStringNoThrow());
}
m = __qmljs_convert_to_object(ctx, object);
- return m->get(name);
+ return m->get(name).asReturnedValue();
}
ReturnedValue __qmljs_get_activation_property(ExecutionContext *ctx, String *name)
{
- return ctx->getProperty(name);
+ return ctx->getProperty(name).asReturnedValue();
}
uint __qmljs_equal_helper(const ValueRef x, const ValueRef y)
context->throwTypeError();
if (o == context->engine->evalFunction && l->name->isEqualTo(context->engine->id_eval))
- return static_cast<EvalFunction *>(o)->evalCall(callData->thisObject, callData->args, callData->argc, true);
+ return static_cast<EvalFunction *>(o)->evalCall(callData->thisObject, callData->args, callData->argc, true).asReturnedValue();
- return o->call(callData);
+ return o->call(callData).asReturnedValue();
}
}
if (o == context->engine->evalFunction && name->isEqualTo(context->engine->id_eval)) {
- return static_cast<EvalFunction *>(o)->evalCall(callData->thisObject, callData->args, callData->argc, true);
+ return static_cast<EvalFunction *>(o)->evalCall(callData->thisObject, callData->args, callData->argc, true).asReturnedValue();
}
- return o->call(callData);
+ return o->call(callData).asReturnedValue();
}
ReturnedValue __qmljs_call_property(ExecutionContext *context, String *name, CallDataRef callData)
context->throwTypeError(error);
}
- return o->call(callData);
+ return o->call(callData).asReturnedValue();
}
ReturnedValue __qmljs_call_property_lookup(ExecutionContext *context, uint index, CallDataRef callData)
if (!o)
context->throwTypeError();
- return o->call(callData);
+ return o->call(callData).asReturnedValue();
}
ReturnedValue __qmljs_call_element(ExecutionContext *context, const ValueRef index, CallDataRef callData)
if (!o)
context->throwTypeError();
- return o->call(callData);
+ return o->call(callData).asReturnedValue();
}
ReturnedValue __qmljs_call_value(ExecutionContext *context, const ValueRef func, CallDataRef callData)
if (!o)
context->throwTypeError();
- return o->call(callData);
+ return o->call(callData).asReturnedValue();
}
if (!f)
context->throwTypeError();
- return f->construct(callData);
+ return f->construct(callData).asReturnedValue();
}
if (!f)
context->throwTypeError();
- return f->construct(callData);
+ return f->construct(callData).asReturnedValue();
}
ReturnedValue __qmljs_construct_value(ExecutionContext *context, const ValueRef func, CallDataRef callData)
if (!f)
context->throwTypeError();
- return f->construct(callData);
+ return f->construct(callData).asReturnedValue();
}
ReturnedValue __qmljs_construct_property(ExecutionContext *context, const ValueRef base, String *name, CallDataRef callData)
if (!f)
context->throwTypeError();
- return f->construct(callData);
+ return f->construct(callData).asReturnedValue();
}
void __qmljs_throw(ExecutionContext *context, const ValueRef value)
res = ctx->engine->id_number;
break;
}
- return Value::fromString(res);
+ return Value::fromString(res).asReturnedValue();
}
QV4::ReturnedValue __qmljs_builtin_typeof_name(ExecutionContext *context, String *name)
}
a->setArrayLengthUnchecked(length);
}
- return Value::fromObject(a);
+ return Value::fromObject(a).asReturnedValue();
}
void __qmljs_builtin_define_getter_setter(ExecutionContext *ctx, const ValueRef object, String *name, const ValueRef getter, const ValueRef setter)
}
}
- return Value::fromObject(o);
+ return Value::fromObject(o).asReturnedValue();
}
QV4::ReturnedValue __qmljs_builtin_setup_arguments_object(ExecutionContext *ctx)
assert(ctx->type >= ExecutionContext::Type_CallContext);
CallContext *c = static_cast<CallContext *>(ctx);
ArgumentsObject *args = new (c->engine->memoryManager) ArgumentsObject(c);
- return Value::fromObject(args);
+ return Value::fromObject(args).asReturnedValue();
}
QV4::ReturnedValue __qmljs_increment(const QV4::ValueRef value)
TRACE1(value);
if (value->isInteger())
- return Value::fromInt32(value->integerValue() + 1);
+ return Value::fromInt32(value->integerValue() + 1).asReturnedValue();
else {
double d = value->toNumber();
- return Value::fromDouble(d + 1);
+ return Value::fromDouble(d + 1).asReturnedValue();
}
}
TRACE1(value);
if (value->isInteger())
- return Value::fromInt32(value->integerValue() - 1);
+ return Value::fromInt32(value->integerValue() - 1).asReturnedValue();
else {
double d = value->toNumber();
- return Value::fromDouble(d - 1);
+ return Value::fromDouble(d - 1).asReturnedValue();
}
}
ReturnedValue __qmljs_value_from_string(String *string)
{
- return Value::fromString(string);
+ return Value::fromString(string).asReturnedValue();
}
ReturnedValue __qmljs_lookup_runtime_regexp(ExecutionContext *ctx, int id)
{
- return ctx->compilationUnit->runtimeRegularExpressions[id];
+ return ctx->compilationUnit->runtimeRegularExpressions[id].asReturnedValue();
}
} // namespace QV4
{
QV4::Object *o = value->asObject();
if (!o)
- return value;
+ return value.asReturnedValue();
return __qmljs_object_default_value(o, typeHint);
}
inline QV4::ReturnedValue __qmljs_to_string(const QV4::ValueRef value, QV4::ExecutionContext *ctx)
{
if (value->isString())
- return *value;
- return QV4::Value::fromString(__qmljs_convert_to_string(ctx, value));
+ return value.asReturnedValue();
+ return __qmljs_convert_to_string(ctx, value)->asReturnedValue();
}
inline QV4::ReturnedValue __qmljs_to_object(QV4::ExecutionContext *ctx, const QV4::ValueRef value)
{
if (value->isObject())
- return *value;
- return QV4::Value::fromObject(__qmljs_convert_to_object(ctx, value));
+ return value.asReturnedValue();
+ return Value::fromObject(__qmljs_convert_to_object(ctx, value)).asReturnedValue();
}
Value result = *value;
if (result.tryIntegerConversion())
- return result;
+ return result.asReturnedValue();
double n = __qmljs_to_number(value);
- return QV4::Value::fromDouble(n);
+ return QV4::Value::fromDouble(n).asReturnedValue();
}
inline QV4::ReturnedValue __qmljs_uminus(const QV4::ValueRef value)
// +0 != -0, so we need to convert to double when negating 0
if (value->isInteger() && value->integerValue())
- return QV4::Value::fromInt32(-value->integerValue());
+ return QV4::Value::fromInt32(-value->integerValue()).asReturnedValue();
else {
double n = __qmljs_to_number(value);
- return QV4::Value::fromDouble(-n);
+ return QV4::Value::fromDouble(-n).asReturnedValue();
}
}
else
n = QV4::Value::toInt32(__qmljs_to_number(value));
- return QV4::Value::fromInt32(~n);
+ return QV4::Value::fromInt32(~n).asReturnedValue();
}
inline QV4::ReturnedValue __qmljs_not(const QV4::ValueRef value)
TRACE1(value);
bool b = value->toBoolean();
- return QV4::Value::fromBoolean(!b);
+ return QV4::Value::fromBoolean(!b).asReturnedValue();
}
// binary operators
TRACE2(left, right);
if (QV4::Value::integerCompatible(*left, *right))
- return QV4::Value::fromInt32(left->integerValue() | right->integerValue());
+ return QV4::Value::fromInt32(left->integerValue() | right->integerValue()).asReturnedValue();
int lval = QV4::Value::toInt32(__qmljs_to_number(left));
int rval = QV4::Value::toInt32(__qmljs_to_number(right));
- return QV4::Value::fromInt32(lval | rval);
+ return QV4::Value::fromInt32(lval | rval).asReturnedValue();
}
inline ReturnedValue __qmljs_bit_xor(const QV4::ValueRef left, const QV4::ValueRef right)
TRACE2(left, right);
if (QV4::Value::integerCompatible(*left, *right))
- return QV4::Value::fromInt32(left->integerValue() ^ right->integerValue());
+ return QV4::Value::fromInt32(left->integerValue() ^ right->integerValue()).asReturnedValue();
int lval = QV4::Value::toInt32(__qmljs_to_number(left));
int rval = QV4::Value::toInt32(__qmljs_to_number(right));
- return QV4::Value::fromInt32(lval ^ rval);
+ return QV4::Value::fromInt32(lval ^ rval).asReturnedValue();
}
inline ReturnedValue __qmljs_bit_and(const QV4::ValueRef left, const QV4::ValueRef right)
TRACE2(left, right);
if (QV4::Value::integerCompatible(*left, *right))
- return QV4::Value::fromInt32(left->integerValue() & right->integerValue());
+ return QV4::Value::fromInt32(left->integerValue() & right->integerValue()).asReturnedValue();
int lval = QV4::Value::toInt32(__qmljs_to_number(left));
int rval = QV4::Value::toInt32(__qmljs_to_number(right));
- return QV4::Value::fromInt32(lval & rval);
+ return QV4::Value::fromInt32(lval & rval).asReturnedValue();
}
inline QV4::ReturnedValue __qmljs_add(QV4::ExecutionContext *ctx, const QV4::ValueRef left, const QV4::ValueRef right)
TRACE2(left, right);
if (QV4::Value::integerCompatible(*left, *right))
- return add_int32(left->integerValue(), right->integerValue());
+ return add_int32(left->integerValue(), right->integerValue()).asReturnedValue();
if (QV4::Value::bothDouble(*left, *right))
- return QV4::Value::fromDouble(left->doubleValue() + right->doubleValue());
+ return QV4::Value::fromDouble(left->doubleValue() + right->doubleValue()).asReturnedValue();
return __qmljs_add_helper(ctx, left, right);
}
TRACE2(left, right);
if (QV4::Value::integerCompatible(*left, *right))
- return sub_int32(left->integerValue(), right->integerValue());
+ return sub_int32(left->integerValue(), right->integerValue()).asReturnedValue();
double lval = __qmljs_to_number(left);
double rval = __qmljs_to_number(right);
- return QV4::Value::fromDouble(lval - rval);
+ return QV4::Value::fromDouble(lval - rval).asReturnedValue();
}
inline QV4::ReturnedValue __qmljs_mul(const QV4::ValueRef left, const QV4::ValueRef right)
TRACE2(left, right);
if (QV4::Value::integerCompatible(*left, *right))
- return mul_int32(left->integerValue(), right->integerValue());
+ return mul_int32(left->integerValue(), right->integerValue()).asReturnedValue();
double lval = __qmljs_to_number(left);
double rval = __qmljs_to_number(right);
- return QV4::Value::fromDouble(lval * rval);
+ return QV4::Value::fromDouble(lval * rval).asReturnedValue();
}
inline QV4::ReturnedValue __qmljs_div(const QV4::ValueRef left, const QV4::ValueRef right)
double lval = __qmljs_to_number(left);
double rval = __qmljs_to_number(right);
- return QV4::Value::fromDouble(lval / rval);
+ return QV4::Value::fromDouble(lval / rval).asReturnedValue();
}
inline QV4::ReturnedValue __qmljs_mod(const QV4::ValueRef left, const QV4::ValueRef right)
if (QV4::Value::integerCompatible(*left, *right) && right->integerValue() != 0) {
int intRes = left->integerValue() % right->integerValue();
if (intRes != 0 || left->integerValue() >= 0)
- return QV4::Value::fromInt32(intRes);
+ return QV4::Value::fromInt32(intRes).asReturnedValue();
}
double lval = __qmljs_to_number(left);
double rval = __qmljs_to_number(right);
- return QV4::Value::fromDouble(std::fmod(lval, rval));
+ return QV4::Value::fromDouble(std::fmod(lval, rval)).asReturnedValue();
}
inline QV4::ReturnedValue __qmljs_shl(const QV4::ValueRef left, const QV4::ValueRef right)
TRACE2(left, right);
if (QV4::Value::integerCompatible(*left, *right))
- return QV4::Value::fromInt32(left->integerValue() << ((uint(right->integerValue()) & 0x1f)));
+ return QV4::Value::fromInt32(left->integerValue() << ((uint(right->integerValue()) & 0x1f))).asReturnedValue();
int lval = QV4::Value::toInt32(__qmljs_to_number(left));
unsigned rval = QV4::Value::toUInt32(__qmljs_to_number(right)) & 0x1f;
- return QV4::Value::fromInt32(lval << rval);
+ return QV4::Value::fromInt32(lval << rval).asReturnedValue();
}
inline QV4::ReturnedValue __qmljs_shr(const QV4::ValueRef left, const QV4::ValueRef right)
TRACE2(left, right);
if (QV4::Value::integerCompatible(*left, *right))
- return QV4::Value::fromInt32(left->integerValue() >> ((uint(right->integerValue()) & 0x1f)));
+ return QV4::Value::fromInt32(left->integerValue() >> ((uint(right->integerValue()) & 0x1f))).asReturnedValue();
int lval = QV4::Value::toInt32(__qmljs_to_number(left));
unsigned rval = QV4::Value::toUInt32(__qmljs_to_number(right)) & 0x1f;
- return QV4::Value::fromInt32(lval >> rval);
+ return QV4::Value::fromInt32(lval >> rval).asReturnedValue();
}
inline QV4::ReturnedValue __qmljs_ushr(const QV4::ValueRef left, const QV4::ValueRef right)
}
if (res > INT_MAX)
- return QV4::Value::fromDouble(res);
+ return QV4::Value::fromDouble(res).asReturnedValue();
else
- return QV4::Value::fromInt32(res);
+ return QV4::Value::fromInt32(res).asReturnedValue();
}
inline QV4::ReturnedValue __qmljs_gt(const QV4::ValueRef left, const QV4::ValueRef right)
{
TRACE2(left, right);
- return QV4::Value::fromBoolean(__qmljs_cmp_gt(left, right));
+ return QV4::Value::fromBoolean(__qmljs_cmp_gt(left, right)).asReturnedValue();
}
inline QV4::ReturnedValue __qmljs_lt(const QV4::ValueRef left, const QV4::ValueRef right)
{
TRACE2(left, right);
- return QV4::Value::fromBoolean(__qmljs_cmp_lt(left, right));
+ return QV4::Value::fromBoolean(__qmljs_cmp_lt(left, right)).asReturnedValue();
}
inline QV4::ReturnedValue __qmljs_ge(const QV4::ValueRef left, const QV4::ValueRef right)
{
TRACE2(left, right);
- return QV4::Value::fromBoolean(__qmljs_cmp_ge(left, right));
+ return QV4::Value::fromBoolean(__qmljs_cmp_ge(left, right)).asReturnedValue();
}
inline QV4::ReturnedValue __qmljs_le(const QV4::ValueRef left, const QV4::ValueRef right)
{
TRACE2(left, right);
- return QV4::Value::fromBoolean(__qmljs_cmp_le(left, right));
+ return QV4::Value::fromBoolean(__qmljs_cmp_le(left, right)).asReturnedValue();
}
inline QV4::ReturnedValue __qmljs_eq(const QV4::ValueRef left, const QV4::ValueRef right)
{
TRACE2(left, right);
- return QV4::Value::fromBoolean(__qmljs_cmp_eq(left, right));
+ return QV4::Value::fromBoolean(__qmljs_cmp_eq(left, right)).asReturnedValue();
}
inline QV4::ReturnedValue __qmljs_ne(const QV4::ValueRef left, const QV4::ValueRef right)
{
TRACE2(left, right);
- return QV4::Value::fromBoolean(!__qmljs_cmp_eq(left, right));
+ return QV4::Value::fromBoolean(!__qmljs_cmp_eq(left, right)).asReturnedValue();
}
inline QV4::ReturnedValue __qmljs_se(const QV4::ValueRef left, const QV4::ValueRef right)
TRACE2(left, right);
bool r = __qmljs_strict_equal(left, right);
- return QV4::Value::fromBoolean(r);
+ return QV4::Value::fromBoolean(r).asReturnedValue();
}
inline QV4::ReturnedValue __qmljs_sne(const QV4::ValueRef left, const QV4::ValueRef right)
TRACE2(left, right);
bool r = ! __qmljs_strict_equal(left, right);
- return QV4::Value::fromBoolean(r);
+ return QV4::Value::fromBoolean(r).asReturnedValue();
}
inline QV4::Bool __qmljs_cmp_eq(const QV4::ValueRef left, const QV4::ValueRef right)
{
TRACE2(left, right);
- QV4::Value v = __qmljs_instanceof(ctx, left, right).get();
- return v.booleanValue();
+ ValueScope scope(ctx);
+ QV4::ScopedValue v(scope, __qmljs_instanceof(ctx, left, right));
+ return v->booleanValue();
}
inline uint __qmljs_cmp_in(QV4::ExecutionContext *ctx, const QV4::ValueRef left, const QV4::ValueRef right)
{
TRACE2(left, right);
- QV4::Value v = __qmljs_in(ctx, left, right).get();
- return v.booleanValue();
+ ValueScope scope(ctx);
+ QV4::ScopedValue v(scope, __qmljs_in(ctx, left, right));
+ return v->booleanValue();
}
} // namespace QV4
struct ScopedValue;
struct ValueRef;
-struct ReturnedValue;
-
-struct ReturnedValue
-{
- inline ReturnedValue(const Value &v);
- inline ReturnedValue(const ValueRef &v);
- inline ReturnedValue(const ScopedValue &v);
- // no destructor or copy constructor!
-
- // ### remove me!
- Value get() const { Value v; v.val = rawValue; return v; }
-private:
- friend struct ValueRef;
- friend struct ScopedValue;
- quint64 rawValue;
-};
struct ScopedValue
{
ScopedValue(const ValueScope &scope, const ReturnedValue &v)
{
ptr = scope.engine->jsStackTop++;
- ptr->val = v.rawValue;
+ ptr->val = v;
}
ScopedValue &operator=(const Value &v) {
}
ScopedValue &operator=(const ReturnedValue &v) {
- ptr->val = v.rawValue;
+ ptr->val = v;
return *this;
}
return *ptr;
}
+ ReturnedValue asReturnedValue() const { return ptr->val; }
+
Value *ptr;
};
ValueRef &operator=(const Value &v)
{ *ptr = v; return *this; }
ValueRef &operator=(const ReturnedValue &v) {
- ptr->val = v.rawValue;
+ ptr->val = v;
return *this;
}
static const ValueRef fromRawValue(const Value *v) {
return ValueRef(const_cast<Value *>(v));
}
+
+ ReturnedValue asReturnedValue() const { return ptr->val; }
+
// ### get rid of this one!
ValueRef(Value *v) { ptr = v; }
private:
- friend class ReturnedValue;
Value *ptr;
};
CallData *ptr;
};
-inline ReturnedValue::ReturnedValue(const Value &v)
- : rawValue(v.val)
-{
-}
-
-inline ReturnedValue::ReturnedValue(const ValueRef &v)
- : rawValue(v.ptr->val)
-{
-}
-
-inline ReturnedValue::ReturnedValue(const ScopedValue &v)
- : rawValue(v.ptr->val)
-{
-}
-
}
QT_END_NAMESPACE
return _text.length();
}
+ ReturnedValue asReturnedValue() { return Value::fromString(this).asReturnedValue(); }
+
QString _text;
mutable Identifier *identifier;
mutable uint stringHash;
inline ExecutionEngine *engine() const;
+ ReturnedValue asReturnedValue() const { return val; }
+ static Value fromReturnedValue(ReturnedValue val) { Value v; v.val = val; return v; }
+
// Section 9.12
bool sameValue(Value other) const;
# define VALUE(param) *getValueRef(context, stack, param, stackSize)
# define VALUEPTR(param) getValueRef(context, stack, param, stackSize)
#endif
+#define STOREVALUE(param, value) VALUE(param) = QV4::Value::fromReturnedValue((value))
QV4::Value VME::run(QV4::ExecutionContext *context, const uchar *&code,
QV4::Value *stack, unsigned stackSize
MOTH_END_INSTR(LoadRegExp)
MOTH_BEGIN_INSTR(LoadClosure)
- VALUE(instr.result) = __qmljs_init_closure(context, instr.value).get();
+ STOREVALUE(instr.result, __qmljs_init_closure(context, instr.value));
MOTH_END_INSTR(LoadClosure)
MOTH_BEGIN_INSTR(LoadName)
TRACE(inline, "property name = %s", instr.name->toQString().toUtf8().constData());
- VALUE(instr.result) = __qmljs_get_activation_property(context, runtimeStrings[instr.name]).get();
+ STOREVALUE(instr.result, __qmljs_get_activation_property(context, runtimeStrings[instr.name]));
MOTH_END_INSTR(LoadName)
MOTH_BEGIN_INSTR(StoreName)
MOTH_END_INSTR(StoreName)
MOTH_BEGIN_INSTR(LoadElement)
- VALUE(instr.result) = __qmljs_get_element(context, VALUEPTR(instr.base), VALUEPTR(instr.index)).get();
+ STOREVALUE(instr.result, __qmljs_get_element(context, VALUEPTR(instr.base), VALUEPTR(instr.index)));
MOTH_END_INSTR(LoadElement)
MOTH_BEGIN_INSTR(StoreElement)
MOTH_END_INSTR(StoreElement)
MOTH_BEGIN_INSTR(LoadProperty)
- VALUE(instr.result) = __qmljs_get_property(context, VALUEPTR(instr.base), runtimeStrings[instr.name]).get();
+ STOREVALUE(instr.result, __qmljs_get_property(context, VALUEPTR(instr.base), runtimeStrings[instr.name]));
MOTH_END_INSTR(LoadProperty)
MOTH_BEGIN_INSTR(StoreProperty)
callData->tag = 0;
callData->argc = instr.argc;
callData->thisObject = QV4::Value::undefinedValue();
- VALUE(instr.result) = __qmljs_call_value(context, VALUEPTR(instr.dest), callData).get();
+ STOREVALUE(instr.result, __qmljs_call_value(context, VALUEPTR(instr.dest), callData));
MOTH_END_INSTR(CallValue)
MOTH_BEGIN_INSTR(CallProperty)
callData->tag = 0;
callData->argc = instr.argc;
callData->thisObject = VALUE(instr.base);
- VALUE(instr.result) = __qmljs_call_property(context, runtimeStrings[instr.name], callData).get();
+ STOREVALUE(instr.result, __qmljs_call_property(context, runtimeStrings[instr.name], callData));
MOTH_END_INSTR(CallProperty)
MOTH_BEGIN_INSTR(CallElement)
callData->tag = 0;
callData->argc = instr.argc;
callData->thisObject = VALUE(instr.base);
- VALUE(instr.result) = __qmljs_call_element(context, VALUEPTR(instr.index), callData).get();
+ STOREVALUE(instr.result, __qmljs_call_element(context, VALUEPTR(instr.index), callData));
MOTH_END_INSTR(CallElement)
MOTH_BEGIN_INSTR(CallActivationProperty)
callData->tag = 0;
callData->argc = instr.argc;
callData->thisObject = QV4::Value::undefinedValue();
- VALUE(instr.result) = __qmljs_call_activation_property(context, runtimeStrings[instr.name], callData).get();
+ STOREVALUE(instr.result, __qmljs_call_activation_property(context, runtimeStrings[instr.name], callData));
MOTH_END_INSTR(CallActivationProperty)
MOTH_BEGIN_INSTR(CallBuiltinThrow)
MOTH_END_INSTR(CallBuiltinPopScope)
MOTH_BEGIN_INSTR(CallBuiltinForeachIteratorObject)
- VALUE(instr.result) = __qmljs_foreach_iterator_object(context, VALUEPTR(instr.arg)).get();
+ STOREVALUE(instr.result, __qmljs_foreach_iterator_object(context, VALUEPTR(instr.arg)));
MOTH_END_INSTR(CallBuiltinForeachIteratorObject)
MOTH_BEGIN_INSTR(CallBuiltinForeachNextPropertyName)
- VALUE(instr.result) = __qmljs_foreach_next_property_name(VALUEPTR(instr.arg)).get();
+ STOREVALUE(instr.result, __qmljs_foreach_next_property_name(VALUEPTR(instr.arg)));
MOTH_END_INSTR(CallBuiltinForeachNextPropertyName)
MOTH_BEGIN_INSTR(CallBuiltinDeleteMember)
- VALUE(instr.result) = __qmljs_delete_member(context, VALUEPTR(instr.base), runtimeStrings[instr.member]).get();
+ STOREVALUE(instr.result, __qmljs_delete_member(context, VALUEPTR(instr.base), runtimeStrings[instr.member]));
MOTH_END_INSTR(CallBuiltinDeleteMember)
MOTH_BEGIN_INSTR(CallBuiltinDeleteSubscript)
- VALUE(instr.result) = __qmljs_delete_subscript(context, VALUEPTR(instr.base), VALUEPTR(instr.index)).get();
+ STOREVALUE(instr.result, __qmljs_delete_subscript(context, VALUEPTR(instr.base), VALUEPTR(instr.index)));
MOTH_END_INSTR(CallBuiltinDeleteSubscript)
MOTH_BEGIN_INSTR(CallBuiltinDeleteName)
- VALUE(instr.result) = __qmljs_delete_name(context, runtimeStrings[instr.name]).get();
+ STOREVALUE(instr.result, __qmljs_delete_name(context, runtimeStrings[instr.name]));
MOTH_END_INSTR(CallBuiltinDeleteName)
MOTH_BEGIN_INSTR(CallBuiltinTypeofMember)
- VALUE(instr.result) = __qmljs_builtin_typeof_member(context, VALUEPTR(instr.base), runtimeStrings[instr.member]).get();
+ STOREVALUE(instr.result, __qmljs_builtin_typeof_member(context, VALUEPTR(instr.base), runtimeStrings[instr.member]));
MOTH_END_INSTR(CallBuiltinTypeofMember)
MOTH_BEGIN_INSTR(CallBuiltinTypeofSubscript)
- VALUE(instr.result) = __qmljs_builtin_typeof_element(context, VALUEPTR(instr.base), VALUEPTR(instr.index)).get();
+ STOREVALUE(instr.result, __qmljs_builtin_typeof_element(context, VALUEPTR(instr.base), VALUEPTR(instr.index)));
MOTH_END_INSTR(CallBuiltinTypeofSubscript)
MOTH_BEGIN_INSTR(CallBuiltinTypeofName)
- VALUE(instr.result) = __qmljs_builtin_typeof_name(context, runtimeStrings[instr.name]).get();
+ STOREVALUE(instr.result, __qmljs_builtin_typeof_name(context, runtimeStrings[instr.name]));
MOTH_END_INSTR(CallBuiltinTypeofName)
MOTH_BEGIN_INSTR(CallBuiltinTypeofValue)
- VALUE(instr.result) = __qmljs_builtin_typeof(context, VALUEPTR(instr.value)).get();
+ STOREVALUE(instr.result, __qmljs_builtin_typeof(context, VALUEPTR(instr.value)));
MOTH_END_INSTR(CallBuiltinTypeofValue)
MOTH_BEGIN_INSTR(CallBuiltinDeclareVar)
MOTH_BEGIN_INSTR(CallBuiltinDefineArray)
Q_ASSERT(instr.args + instr.argc <= stackSize);
QV4::Value *args = stack + instr.args;
- VALUE(instr.result) = __qmljs_builtin_define_array(context, args, instr.argc).get();
+ STOREVALUE(instr.result, __qmljs_builtin_define_array(context, args, instr.argc));
MOTH_END_INSTR(CallBuiltinDefineArray)
MOTH_BEGIN_INSTR(CallBuiltinDefineObjectLiteral)
QV4::Value *args = stack + instr.args;
- VALUE(instr.result) = __qmljs_builtin_define_object_literal(context, args, instr.internalClassId).get();
+ STOREVALUE(instr.result, __qmljs_builtin_define_object_literal(context, args, instr.internalClassId));
MOTH_END_INSTR(CallBuiltinDefineObjectLiteral)
MOTH_BEGIN_INSTR(CallBuiltinSetupArgumentsObject)
- VALUE(instr.result) = __qmljs_builtin_setup_arguments_object(context).get();
+ STOREVALUE(instr.result, __qmljs_builtin_setup_arguments_object(context));
MOTH_END_INSTR(CallBuiltinSetupArgumentsObject)
MOTH_BEGIN_INSTR(CreateValue)
callData->tag = 0;
callData->argc = instr.argc;
callData->thisObject = QV4::Value::undefinedValue();
- VALUE(instr.result) = __qmljs_construct_value(context, VALUEPTR(instr.func), callData).get();
+ STOREVALUE(instr.result, __qmljs_construct_value(context, VALUEPTR(instr.func), callData));
MOTH_END_INSTR(CreateValue)
MOTH_BEGIN_INSTR(CreateProperty)
callData->tag = 0;
callData->argc = instr.argc;
callData->thisObject = QV4::Value::undefinedValue();
- VALUE(instr.result) = __qmljs_construct_property(context, VALUEPTR(instr.base), runtimeStrings[instr.name], callData).get();
+ STOREVALUE(instr.result, __qmljs_construct_property(context, VALUEPTR(instr.base), runtimeStrings[instr.name], callData));
MOTH_END_INSTR(CreateProperty)
MOTH_BEGIN_INSTR(CreateActivationProperty)
callData->tag = 0;
callData->argc = instr.argc;
callData->thisObject = QV4::Value::undefinedValue();
- VALUE(instr.result) = __qmljs_construct_activation_property(context, runtimeStrings[instr.name], callData).get();
+ STOREVALUE(instr.result, __qmljs_construct_activation_property(context, runtimeStrings[instr.name], callData));
MOTH_END_INSTR(CreateActivationProperty)
MOTH_BEGIN_INSTR(Jump)
MOTH_END_INSTR(CJump)
MOTH_BEGIN_INSTR(Unop)
- VALUE(instr.result) = instr.alu(VALUEPTR(instr.source)).get();
+ STOREVALUE(instr.result, instr.alu(VALUEPTR(instr.source)));
MOTH_END_INSTR(Unop)
MOTH_BEGIN_INSTR(Binop)
- VALUE(instr.result) = instr.alu(VALUEPTR(instr.lhs), VALUEPTR(instr.rhs)).get();
+ STOREVALUE(instr.result, instr.alu(VALUEPTR(instr.lhs), VALUEPTR(instr.rhs)));
MOTH_END_INSTR(Binop)
MOTH_BEGIN_INSTR(BinopContext)
- VALUE(instr.result) = instr.alu(context, VALUEPTR(instr.lhs), VALUEPTR(instr.rhs)).get();
+ STOREVALUE(instr.result, instr.alu(context, VALUEPTR(instr.lhs), VALUEPTR(instr.rhs)));
MOTH_END_INSTR(BinopContext)
MOTH_BEGIN_INSTR(AddNumberParams)