From: Roberto Raggi Date: Fri, 18 May 2012 20:04:26 +0000 (+0200) Subject: Initial support for inplace assignments. X-Git-Tag: upstream/5.2.1~669^2~659^2~1180 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e8bd50dd950f9f7a4bfb892cae0e12934419aca3;p=platform%2Fupstream%2Fqtdeclarative.git Initial support for inplace assignments. --- diff --git a/qmljs_runtime.cpp b/qmljs_runtime.cpp index 40f0b96..b83cc32 100644 --- a/qmljs_runtime.cpp +++ b/qmljs_runtime.cpp @@ -438,7 +438,7 @@ void __qmljs_set_activation_property(Context *ctx, String *name, Value *value) if (Value *prop = ctx->lookup(name)) { *prop = *value; } else - ctx->activation.objectValue->put(name, *value); + ctx->engine->globalObject.objectValue->put(name, *value); } void __qmljs_copy_activation_property(Context *ctx, String *name, String *other) diff --git a/qmljs_runtime.h b/qmljs_runtime.h index 2dd4f85..9837a46 100644 --- a/qmljs_runtime.h +++ b/qmljs_runtime.h @@ -555,6 +555,83 @@ inline void __qmljs_bit_and(Context *ctx, Value *result, const Value *left, cons __qmljs_init_number(result, lval & rval); } +inline void __qmljs_inplace_bit_and(Context *ctx, Value *result, double value) +{ + Value v; + __qmljs_init_number(&v, value); + __qmljs_bit_xor(ctx, result, result, &v); +} + +inline void __qmljs_inplace_bit_or(Context *ctx, Value *result, double value) +{ + Value v; + __qmljs_init_number(&v, value); + __qmljs_bit_or(ctx, result, result, &v); +} + +inline void __qmljs_inplace_bit_xor(Context *ctx, Value *result, double value) +{ + Value v; + __qmljs_init_number(&v, value); + __qmljs_bit_xor(ctx, result, result, &v); +} + +inline void __qmljs_inplace_add(Context *ctx, Value *result, double value) +{ + Value v; + __qmljs_init_number(&v, value); + __qmljs_add(ctx, result, result, &v); +} + +inline void __qmljs_inplace_sub(Context *ctx, Value *result, double value) +{ + Value v; + __qmljs_init_number(&v, value); + __qmljs_sub(ctx, result, result, &v); +} + +inline void __qmljs_inplace_mul(Context *ctx, Value *result, double value) +{ + Value v; + __qmljs_init_number(&v, value); + __qmljs_mul(ctx, result, result, &v); +} + +inline void __qmljs_inplace_div(Context *ctx, Value *result, double value) +{ + Value v; + __qmljs_init_number(&v, value); + __qmljs_div(ctx, result, result, &v); +} + +inline void __qmljs_inplace_mod(Context *ctx, Value *result, double value) +{ + Value v; + __qmljs_init_number(&v, value); + __qmljs_mod(ctx, result, result, &v); +} + +inline void __qmljs_inplace_shl(Context *ctx, Value *result, double value) +{ + Value v; + __qmljs_init_number(&v, value); + __qmljs_shl(ctx, result, result, &v); +} + +inline void __qmljs_inplace_shr(Context *ctx, Value *result, double value) +{ + Value v; + __qmljs_init_number(&v, value); + __qmljs_shr(ctx, result, result, &v); +} + +inline void __qmljs_inplace_ushr(Context *ctx, Value *result, double value) +{ + Value v; + __qmljs_init_number(&v, value); + __qmljs_ushr(ctx, result, result, &v); +} + inline void __qmljs_add(Context *ctx, Value *result, const Value *left, const Value *right) { Value pleft, pright; diff --git a/qv4codegen.cpp b/qv4codegen.cpp index 9226749..6abd114 100644 --- a/qv4codegen.cpp +++ b/qv4codegen.cpp @@ -920,11 +920,13 @@ bool Codegen::visit(BinaryExpression *ast) case QSOperator::InplaceRightShift: case QSOperator::InplaceURightShift: case QSOperator::InplaceXor: { - move(*left, *right, baseOp(ast->op)); if (_expr.accept(nx)) { - // nothing to do + move(*left, *right, baseOp(ast->op)); } else { - _expr.code = *left; + const unsigned t = _block->newTemp(); + move(_block->TEMP(t), *right); + move(*left, _block->TEMP(t), baseOp(ast->op)); + _expr.code = _block->TEMP(t); } break; } diff --git a/qv4isel.cpp b/qv4isel.cpp index 42e0084..6120609 100644 --- a/qv4isel.cpp +++ b/qv4isel.cpp @@ -676,26 +676,79 @@ void InstructionSelection::visitMove(IR::Move *s) // inplace assignment, e.g. x += 1, ++x, ... if (IR::Temp *t = s->target->asTemp()) { if (IR::Const *c = s->source->asConst()) { + amd64_mov_reg_reg(_codePtr, AMD64_RDI, AMD64_R14, 8); + loadTempAddress(AMD64_RSI, t); + amd64_mov_reg_imm(_codePtr, AMD64_RAX, &c->value); + amd64_movsd_reg_regp(_codePtr, X86_XMM0, AMD64_RAX); + + void (*op)(Context *, Value *, double); + switch (s->op) { + case QQmlJS::IR::OpBitAnd: op = __qmljs_inplace_bit_and; break; + case QQmlJS::IR::OpBitOr: op = __qmljs_inplace_bit_or; break; + case QQmlJS::IR::OpBitXor: op = __qmljs_inplace_bit_xor; break; + case QQmlJS::IR::OpAdd: op = __qmljs_inplace_add; break; + case QQmlJS::IR::OpSub: op = __qmljs_inplace_sub; break; + case QQmlJS::IR::OpMul: op = __qmljs_inplace_mul; break; + case QQmlJS::IR::OpDiv: op = __qmljs_inplace_div; break; + case QQmlJS::IR::OpMod: op = __qmljs_inplace_mod; break; + case QQmlJS::IR::OpLShift: op = __qmljs_inplace_shl; break; + case QQmlJS::IR::OpRShift: op = __qmljs_inplace_shr; break; + case QQmlJS::IR::OpURShift: op = __qmljs_inplace_ushr; break; + default: + Q_UNREACHABLE(); + break; + } + + amd64_call_code(_codePtr, op); return; } else if (IR::Temp *t2 = s->source->asTemp()) { + amd64_mov_reg_reg(_codePtr, AMD64_RDI, AMD64_R14, 8); + loadTempAddress(AMD64_RSI, t); + loadTempAddress(AMD64_RDX, t); + loadTempAddress(AMD64_RCX, t2); + void (*op)(Context *, Value *, const Value *, const Value *); + switch (s->op) { + case QQmlJS::IR::OpBitAnd: op = __qmljs_bit_and; break; + case QQmlJS::IR::OpBitOr: op = __qmljs_bit_or; break; + case QQmlJS::IR::OpBitXor: op = __qmljs_bit_xor; break; + case QQmlJS::IR::OpAdd: op = __qmljs_add; break; + case QQmlJS::IR::OpSub: op = __qmljs_sub; break; + case QQmlJS::IR::OpMul: op = __qmljs_mul; break; + case QQmlJS::IR::OpDiv: op = __qmljs_div; break; + case QQmlJS::IR::OpMod: op = __qmljs_mod; break; + case QQmlJS::IR::OpLShift: op = __qmljs_shl; break; + case QQmlJS::IR::OpRShift: op = __qmljs_shr; break; + case QQmlJS::IR::OpURShift: op = __qmljs_ushr; break; + default: + Q_UNREACHABLE(); + break; + } + + amd64_call_code(_codePtr, op); return; } } else if (IR::Name *n = s->target->asName()) { if (IR::Const *c = s->source->asConst()) { + assert(!"wip"); return; } else if (IR::Temp *t = s->source->asTemp()) { + assert(!"wip"); return; } } else if (IR::Subscript *ss = s->target->asSubscript()) { if (IR::Const *c = s->source->asConst()) { + assert(!"wip"); return; } else if (IR::Temp *t = s->source->asTemp()) { + assert(!"wip"); return; } } else if (IR::Member *m = s->target->asMember()) { if (IR::Const *c = s->source->asConst()) { + assert(!"wip"); return; } else if (IR::Temp *t = s->source->asTemp()) { + assert(!"wip"); return; } } @@ -725,12 +778,12 @@ void InstructionSelection::visitCJump(IR::CJump *s) amd64_alu_reg_imm(_codePtr, X86_CMP, AMD64_RAX, BOOLEAN_TYPE); uchar *label1 = _codePtr; - amd64_branch32(_codePtr, X86_CC_NE, 0, 0); + amd64_branch8(_codePtr, X86_CC_NE, 0, 0); amd64_mov_reg_membase(_codePtr, AMD64_RAX, AMD64_RSI, offsetof(Value, booleanValue), 1); uchar *label2 = _codePtr; - amd64_jump32(_codePtr, 0); + amd64_jump8(_codePtr, 0); amd64_patch(label1, _codePtr); amd64_call_code(_codePtr, __qmljs_to_boolean);