See https://codereview.qt-project.org/39510 for details.
Change-Id: I308364cd7d66ad2fd12e6ab7e185882fe8d1795e
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
struct instr_storeName {
MOTH_INSTR_HEADER
VM::String *name;
- int sourceTemp;
+ ValueOrTemp source;
+ unsigned sourceIsTemp:1;
};
struct instr_loadProperty {
MOTH_INSTR_HEADER
};
struct instr_storeProperty {
MOTH_INSTR_HEADER
- int sourceTemp;
int baseTemp;
VM::String *name;
+ ValueOrTemp source;
+ unsigned sourceIsTemp:1;
};
struct instr_loadElement {
MOTH_INSTR_HEADER
};
struct instr_storeElement {
MOTH_INSTR_HEADER
- int sourceTemp;
int base;
int index;
+ ValueOrTemp source;
+ unsigned sourceIsTemp:1;
};
struct instr_push {
MOTH_INSTR_HEADER
void (*alu)(VM::Value, VM::Value, VM::Value, VM::Context *);
int targetBase;
int targetIndex;
- int source;
+ ValueOrTemp source;
+ unsigned sourceIsTemp:1;
};
struct instr_inplaceMemberOp {
MOTH_INSTR_HEADER
void (*alu)(VM::Value, VM::Value, VM::String *, VM::Context *);
int targetBase;
VM::String *targetMember;
- int source;
+ ValueOrTemp source;
+ unsigned sourceIsTemp:1;
};
struct instr_inplaceNameOp {
MOTH_INSTR_HEADER
void (*alu)(VM::Value, VM::String *, VM::Context *);
VM::String *targetName;
- int source;
+ ValueOrTemp source;
+ unsigned sourceIsTemp:1;
};
instr_common common;
}
return;
} else if (IR::Name *n = s->target->asName()) {
- if (IR::Temp *t = s->source->asTemp()) {
+ if (s->source->asTemp() || s->source->asConst()) {
void (*op)(VM::Value value, VM::String *name, VM::Context *ctx) = 0;
switch (s->op) {
case IR::OpBitAnd: op = VM::__qmljs_inplace_bit_and_name; break;
Instruction::InplaceNameOp ieo;
ieo.alu = op;
ieo.targetName = _engine->newString(*n->id);
- ieo.source = t->index;
+ ieo.sourceIsTemp = toValueOrTemp(s->source, ieo.source);
addInstruction(ieo);
return;
} else if (s->op == IR::OpInvalid) {
Instruction::StoreName store;
- store.sourceTemp = t->index;
+ store.sourceIsTemp = toValueOrTemp(s->source, store.source);
store.name = _engine->newString(*n->id);
addInstruction(store);
return;
}
qWarning("NAME");
} else if (IR::Subscript *ss = s->target->asSubscript()) {
- if (IR::Temp *t = s->source->asTemp()) {
+ if (s->source->asTemp() || s->source->asConst()) {
void (*op)(VM::Value base, VM::Value index, VM::Value value, VM::Context *ctx) = 0;
switch (s->op) {
case IR::OpBitAnd: op = VM::__qmljs_inplace_bit_and_element; break;
ieo.alu = op;
ieo.targetBase = ss->base->asTemp()->index;
ieo.targetIndex = ss->index->asTemp()->index;
- ieo.source = t->index;
+ ieo.sourceIsTemp = toValueOrTemp(s->source, ieo.source);
addInstruction(ieo);
return;
} else if (s->op == IR::OpInvalid) {
Instruction::StoreElement store;
- store.sourceTemp = t->index;
store.base = ss->base->asTemp()->index;
store.index = ss->index->asTemp()->index;
+ store.sourceIsTemp = toValueOrTemp(s->source, store.source);
addInstruction(store);
return;
}
}
qWarning("SUBSCRIPT");
} else if (IR::Member *m = s->target->asMember()) {
- if (IR::Temp *t = s->source->asTemp()) {
+ if (s->source->asTemp() || s->source->asConst()) {
void (*op)(VM::Value value, VM::Value base, VM::String *name, VM::Context *ctx) = 0;
switch (s->op) {
case IR::OpBitAnd: op = VM::__qmljs_inplace_bit_and_member; break;
imo.alu = op;
imo.targetBase = m->base->asTemp()->index;
imo.targetMember = _engine->newString(*m->name);
- imo.source = t->index;
+ imo.sourceIsTemp = toValueOrTemp(s->source, imo.source);
addInstruction(imo);
return;
} else if (s->op == IR::OpInvalid) {
Instruction::StoreProperty store;
- store.sourceTemp = t->index;
store.baseTemp = m->base->asTemp()->index;
store.name = _engine->newString(*m->name);
+ store.sourceIsTemp = toValueOrTemp(s->source, store.source);
addInstruction(store);
return;
}
MOTH_BEGIN_INSTR(StoreName)
TRACE(inline, "property name = %s", instr.name->toQString().toUtf8().constData());
- __qmljs_set_activation_property(context, instr.name, TEMP(instr.sourceTemp));
+ VM::Value source = instr.sourceIsTemp ? TEMP(instr.source.tempIndex) : instr.source.value;
+ __qmljs_set_activation_property(context, instr.name, source);
MOTH_END_INSTR(StoreName)
MOTH_BEGIN_INSTR(LoadElement)
MOTH_END_INSTR(LoadElement)
MOTH_BEGIN_INSTR(StoreElement)
- __qmljs_set_element(context, TEMP(instr.base), TEMP(instr.index), TEMP(instr.sourceTemp));
+ VM::Value source = instr.sourceIsTemp ? TEMP(instr.source.tempIndex) : instr.source.value;
+ __qmljs_set_element(context, TEMP(instr.base), TEMP(instr.index), source);
MOTH_END_INSTR(StoreElement)
MOTH_BEGIN_INSTR(LoadProperty)
MOTH_BEGIN_INSTR(StoreProperty)
TRACE(inline, "base temp = %d, property name = %s", instr.baseTemp, instr.name->toQString().toUtf8().constData());
VM::Value base = TEMP(instr.baseTemp);
- __qmljs_set_property(context, base, instr.name, TEMP(instr.sourceTemp));
+ VM::Value source = instr.sourceIsTemp ? TEMP(instr.source.tempIndex) : instr.source.value;
+ __qmljs_set_property(context, base, instr.name, source);
MOTH_END_INSTR(StoreProperty)
MOTH_BEGIN_INSTR(Push)
MOTH_END_INSTR(LoadThis)
MOTH_BEGIN_INSTR(InplaceElementOp)
+ VM::Value source = instr.sourceIsTemp ? TEMP(instr.source.tempIndex) : instr.source.value;
instr.alu(TEMP(instr.targetBase),
TEMP(instr.targetIndex),
- TEMP(instr.source),
+ source,
context);
MOTH_END_INSTR(InplaceElementOp)
MOTH_BEGIN_INSTR(InplaceMemberOp)
- instr.alu(TEMP(instr.source),
+ VM::Value source = instr.sourceIsTemp ? TEMP(instr.source.tempIndex) : instr.source.value;
+ instr.alu(source,
TEMP(instr.targetBase),
instr.targetMember,
context);
MOTH_END_INSTR(InplaceMemberOp)
MOTH_BEGIN_INSTR(InplaceNameOp)
- instr.alu(TEMP(instr.source),
+ VM::Value source = instr.sourceIsTemp ? TEMP(instr.source.tempIndex) : instr.source.value;
+ instr.alu(source,
instr.targetName,
context);
MOTH_END_INSTR(InplaceNameOp)
IR::Subscript *subscript = s->target->asSubscript();
llvm::Value *base = getLLVMTempReference(subscript->base);
llvm::Value *index = getLLVMTempReference(subscript->index);
- llvm::Value *source = getLLVMTempReference(s->source);
+ llvm::Value *source = toValuePtr(s->source);
CreateCall4(_llvmModule->getFunction("__qmljs_llvm_set_element"),
_llvmFunction->arg_begin(), base, index, source);
}
IR::Member *m = s->target->asMember();
llvm::Value *base = getLLVMTempReference(m->base);
llvm::Value *name = getIdentifier(*m->name);
- llvm::Value *source = getLLVMTempReference(s->source);
+ llvm::Value *source = toValuePtr(s->source);
CreateCall4(_llvmModule->getFunction("__qmljs_llvm_set_property"),
_llvmFunction->arg_begin(), base, name, source);
}
return;
} else if (IR::Name *n = s->target->asName()) {
llvm::Value *name = getIdentifier(*n->id);
- llvm::Value *source = getLLVMTempReference(s->source);
+ llvm::Value *source = toValuePtr(s->source);
CreateCall3(_llvmModule->getFunction("__qmljs_llvm_set_activation_property"),
_llvmFunction->arg_begin(), name, source);
return;
}
} else {
if (IR::Temp *t = s->target->asTemp()) {
- if (IR::Temp *t2 = s->source->asTemp()) {
+ if (s->source->asTemp() || s->source->asConst()) {
const char *opName = 0;
switch (s->op) {
case IR::OpBitAnd: opName = "__qmljs_llvm_bit_and"; break;
if (opName) {
llvm::Value *target = getLLVMTemp(t);
- llvm::Value *s1 = getLLVMTemp(t);
- llvm::Value *s2 = getLLVMTemp(t2);
+ llvm::Value *s1 = toValuePtr(s->target);
+ llvm::Value *s2 = toValuePtr(s->source);
CreateCall4(_llvmModule->getFunction(opName),
_llvmFunction->arg_begin(), target, s1, s2);
return;
}
} else if (IR::Name *n = s->target->asName()) {
// inplace assignment, e.g. x += 1, ++x, ...
- if (IR::Temp *t = s->source->asTemp()) {
+ if (s->source->asTemp() || s->source->asConst()) {
const char *opName = 0;
switch (s->op) {
case IR::OpBitAnd: opName = "__qmljs_llvm_inplace_bit_and_name"; break;
if (opName) {
llvm::Value *dst = getIdentifier(*n->id);
- llvm::Value *src = getLLVMTemp(t);
+ llvm::Value *src = toValuePtr(s->source);
CreateCall3(_llvmModule->getFunction(opName),
_llvmFunction->arg_begin(), dst, src);
return;
}
}
} else if (IR::Subscript *ss = s->target->asSubscript()) {
- if (IR::Temp *t = s->source->asTemp()) {
+ if (s->source->asTemp() || s->source->asConst()) {
const char *opName = 0;
switch (s->op) {
case IR::OpBitAnd: opName = "__qmljs_llvm_inplace_bit_and_element"; break;
if (opName) {
llvm::Value *base = getLLVMTemp(ss->base->asTemp());
llvm::Value *index = getLLVMTemp(ss->index->asTemp());
- llvm::Value *value = getLLVMTemp(t);
+ llvm::Value *value = toValuePtr(s->source);
CreateCall4(_llvmModule->getFunction(opName),
_llvmFunction->arg_begin(), base, index, value);
// TODO: checkExceptions();
return;
}
} else if (IR::Member *m = s->target->asMember()) {
- if (IR::Temp *t = s->source->asTemp()) {
+ if (s->source->asTemp() || s->source->asConst()) {
const char *opName = 0;
switch (s->op) {
case IR::OpBitAnd: opName = "__qmljs_llvm_inplace_bit_and_member"; break;
if (opName) {
llvm::Value *base = getLLVMTemp(m->base->asTemp());
llvm::Value *member = getIdentifier(*m->name);
- llvm::Value *value = getLLVMTemp(t);
+ llvm::Value *value = toValuePtr(s->source);
CreateCall4(_llvmModule->getFunction(opName),
_llvmFunction->arg_begin(), value, base, member);
// TODO: checkExceptions();