void __qmljs_llvm_get_element(ExecutionContext *ctx, Value *result, Value *object, Value *index)
{
- *result = __qmljs_get_element(ctx, *object, *index);
+ __qmljs_get_element(ctx, result, *object, *index);
}
void __qmljs_llvm_set_element(ExecutionContext *ctx, Value *object, Value *index, Value *value)
addInstruction(load);
}
-void InstructionSelection::setElement(IR::Expr *source, IR::Temp *targetBase, IR::Temp *targetIndex)
+void InstructionSelection::setElement(IR::Temp *source, IR::Temp *targetBase, IR::Temp *targetIndex)
{
Instruction::StoreElement store;
store.base = getParam(targetBase);
virtual void getProperty(IR::Temp *base, const QString &name, IR::Temp *target);
virtual void setProperty(IR::Temp *source, IR::Temp *targetBase, const QString &targetName);
virtual void getElement(IR::Temp *base, IR::Temp *index, IR::Temp *target);
- virtual void setElement(IR::Expr *source, IR::Temp *targetBase, IR::Temp *targetIndex);
+ virtual void setElement(IR::Temp *source, IR::Temp *targetBase, IR::Temp *targetIndex);
virtual void copyValue(IR::Temp *sourceTemp, IR::Temp *targetTemp);
virtual void unop(IR::AluOp oper, IR::Temp *sourceTemp, IR::Temp *targetTemp);
virtual void binop(IR::AluOp oper, IR::Temp *leftSource, IR::Temp *rightSource, IR::Temp *target);
MOTH_END_INSTR(StoreName)
MOTH_BEGIN_INSTR(LoadElement)
- VALUE(instr.result) = __qmljs_get_element(context, VALUE(instr.base), VALUE(instr.index));
+ __qmljs_get_element(context, VALUEPTR(instr.result), VALUE(instr.base), VALUE(instr.index));
MOTH_END_INSTR(LoadElement)
MOTH_BEGIN_INSTR(StoreElement)
o->__put__(ctx, name, value);
}
-Value __qmljs_get_element(ExecutionContext *ctx, Value object, Value index)
+void __qmljs_get_element(ExecutionContext *ctx, Value *result, const Value &object, const Value &index)
{
uint type = object.type();
uint idx = index.asArrayIndex();
- if (type != Value::Object_Type) {
+ Object *o = object.asObject();
+ if (!o) {
if (type == Value::String_Type && idx < UINT_MAX) {
String *str = object.stringValue();
- if (idx >= (uint)str->toQString().length())
- return Value::undefinedValue();
+ if (idx >= (uint)str->toQString().length()) {
+ if (result)
+ *result = Value::undefinedValue();
+ return;
+ }
const QString s = str->toQString().mid(idx, 1);
- return Value::fromString(ctx, s);
+ if (result)
+ *result = Value::fromString(ctx, s);
+ return;
}
- object = __qmljs_to_object(object, ctx);
+ o = __qmljs_to_object(object, ctx).objectValue();
}
- Object *o = object.objectValue();
-
if (idx < UINT_MAX) {
const PropertyDescriptor *p = o->nonSparseArrayAt(idx);
- if (p && p->type == PropertyDescriptor::Data)
- return p->value;
+ if (p && p->type == PropertyDescriptor::Data) {
+ if (result)
+ *result = p->value;
+ return;
+ }
- return o->__get__(ctx, idx);
+ Value res = o->__get__(ctx, idx);
+ if (result)
+ *result = res;
+ return;
}
String *name = index.toString(ctx);
- return o->__get__(ctx, name);
+ Value res = o->__get__(ctx, name);
+ if (result)
+ *result = res;
}
-void __qmljs_set_element(ExecutionContext *ctx, Value object, Value index, Value value)
+void __qmljs_set_element(ExecutionContext *ctx, const Value &object, const Value &index, const Value &value)
{
- if (!object.isObject())
- object = __qmljs_to_object(object, ctx);
-
- Object *o = object.objectValue();
+ Object *o = __qmljs_to_object(object, ctx).objectValue();
uint idx = index.asArrayIndex();
if (idx < UINT_MAX) {
void __qmljs_set_property_lookup(ExecutionContext *ctx, const Value &object, int lookupIndex, const Value &value);
-Value __qmljs_get_element(ExecutionContext *ctx, Value object, Value index);
-void __qmljs_set_element(ExecutionContext *ctx, Value object, Value index, Value value);
+void __qmljs_get_element(ExecutionContext *ctx, Value *retval, const Value &object, const Value &index);
+void __qmljs_set_element(ExecutionContext *ctx, const Value &object, const Value &index, const Value &value);
// For each
Value __qmljs_foreach_iterator_object(Value in, ExecutionContext *ctx);
inline Value __qmljs_to_object(const Value &value, ExecutionContext *ctx)
{
+ if (value.isObject())
+ return value;
+
switch (value.type()) {
case Value::Undefined_Type:
case Value::Null_Type:
return __qmljs_new_string_object(ctx, value.stringValue());
break;
case Value::Object_Type:
- return value;
+ Q_UNREACHABLE();
break;
case Value::Integer_Type:
return __qmljs_new_number_object(ctx, value.int_32);
_llvmFunction->arg_begin(), t, base, index);
}
-void InstructionSelection::setElement(IR::Expr *source, IR::Temp *targetBase, IR::Temp *targetIndex)
+void InstructionSelection::setElement(IR::Temp *source, IR::Temp *targetBase, IR::Temp *targetIndex)
{
llvm::Value *base = getLLVMTempReference(targetBase);
llvm::Value *index = getLLVMTempReference(targetIndex);
virtual void getProperty(IR::Temp *sourceBase, const QString &sourceName, IR::Temp *target);
virtual void setProperty(IR::Temp *source, IR::Temp *targetBase, const QString &targetName);
virtual void getElement(IR::Temp *sourceBase, IR::Temp *sourceIndex, IR::Temp *target);
- virtual void setElement(IR::Expr *source, IR::Temp *targetBase, IR::Temp *targetIndex);
+ virtual void setElement(IR::Temp *source, IR::Temp *targetBase, IR::Temp *targetIndex);
virtual void copyValue(IR::Temp *sourceTemp, IR::Temp *targetTemp);
virtual void unop(IR::AluOp oper, IR::Temp *sourceTemp, IR::Temp *targetTemp);
virtual void binop(IR::AluOp oper, IR::Temp *leftSource, IR::Temp *rightSource, IR::Temp *target);
void InstructionSelection::getElement(IR::Temp *base, IR::Temp *index, IR::Temp *target)
{
- generateFunctionCall(target, __qmljs_get_element, Assembler::ContextRegister, base, index);
+ generateFunctionCall(Assembler::Void, __qmljs_get_element, Assembler::ContextRegister,
+ Assembler::PointerToValue(target), Assembler::PointerToValue(base), Assembler::PointerToValue(index));
}
-void InstructionSelection::setElement(IR::Expr *source, IR::Temp *targetBase, IR::Temp *targetIndex)
+void InstructionSelection::setElement(IR::Temp *source, IR::Temp *targetBase, IR::Temp *targetIndex)
{
- generateFunctionCall(Assembler::Void, __qmljs_set_element, Assembler::ContextRegister, targetBase, targetIndex, source);
+ generateFunctionCall(Assembler::Void, __qmljs_set_element, Assembler::ContextRegister,
+ Assembler::PointerToValue(targetBase), Assembler::PointerToValue(targetIndex), Assembler::PointerToValue(source));
}
void InstructionSelection::copyValue(IR::Temp *sourceTemp, IR::Temp *targetTemp)
virtual void getProperty(IR::Temp *base, const QString &name, IR::Temp *target);
virtual void setProperty(IR::Temp *source, IR::Temp *targetBase, const QString &targetName);
virtual void getElement(IR::Temp *base, IR::Temp *index, IR::Temp *target);
- virtual void setElement(IR::Expr *source, IR::Temp *targetBase, IR::Temp *targetIndex);
+ virtual void setElement(IR::Temp *source, IR::Temp *targetBase, IR::Temp *targetIndex);
virtual void copyValue(IR::Temp *sourceTemp, IR::Temp *targetTemp);
virtual void unop(IR::AluOp oper, IR::Temp *sourceTemp, IR::Temp *targetTemp);
virtual void binop(IR::AluOp oper, IR::Temp *leftSource, IR::Temp *rightSource, IR::Temp *target);
}
}
} else if (IR::Subscript *ss = s->target->asSubscript()) {
- if (s->source->asTemp() || s->source->asConst()) {
- setElement(s->source, ss->base->asTemp(), ss->index->asTemp());
+ if (s->source->asTemp()) {
+ setElement(s->source->asTemp(), ss->base->asTemp(), ss->index->asTemp());
return;
}
}
virtual void getProperty(IR::Temp *base, const QString &name, IR::Temp *target) = 0;
virtual void setProperty(IR::Temp *source, IR::Temp *targetBase, const QString &targetName) = 0;
virtual void getElement(IR::Temp *base, IR::Temp *index, IR::Temp *target) = 0;
- virtual void setElement(IR::Expr *source, IR::Temp *targetBase, IR::Temp *targetIndex) = 0;
+ virtual void setElement(IR::Temp *source, IR::Temp *targetBase, IR::Temp *targetIndex) = 0;
virtual void copyValue(IR::Temp *sourceTemp, IR::Temp *targetTemp) = 0;
virtual void unop(IR::AluOp oper, IR::Temp *sourceTemp, IR::Temp *targetTemp) = 0;
virtual void binop(IR::AluOp oper, IR::Temp *leftSource, IR::Temp *rightSource, IR::Temp *target) = 0;