void __qmljs_llvm_call_value(Context *context, Value *result, const Value *thisObject, const Value *func, Value *args, int argc)
{
- __qmljs_call_value(context, result, thisObject, func, args, argc);
+ Value that = thisObject ? *thisObject : Value::undefinedValue();
+ *result = __qmljs_call_value(context, that, func, args, argc);
}
void __qmljs_llvm_construct_activation_property(Context *context, Value *result, String *name, Value *args, int argc)
void __qmljs_llvm_call_property(Context *context, Value *result, const Value *base, String *name, Value *args, int argc)
{
- __qmljs_call_property(context, result, base, name, args, argc);
+ *result = __qmljs_call_property(context, *base, name, args, argc);
}
void __qmljs_llvm_construct_property(Context *context, Value *result, const Value *base, String *name, Value *args, int argc)
MOTH_BEGIN_INSTR(Call)
VM::Value *args = stack.data() + instr.args;
- __qmljs_call_value(context, &tempRegister, /*thisObject=*/0, &tempRegister, args, instr.argc);
+ tempRegister = __qmljs_call_value(context, VM::Value::undefinedValue(), &tempRegister, args, instr.argc);
MOTH_END_INSTR(Call)
MOTH_BEGIN_INSTR(Jump)
std::fill(locals, locals + varCount, Value::undefinedValue());
}
-void Context::leaveCallContext(FunctionObject *f, Value *returnValue)
+void Context::leaveCallContext(FunctionObject *f)
{
- if (returnValue)
- *returnValue = result;
-
if (! f->needsActivation) {
delete[] locals;
locals = 0;
if (! thisObject.isObject())
thisObject.objectValue()->prototype = engine->objectPrototype;
- leaveCallContext(f, returnValue);
+ leaveCallContext(f);
+ *returnValue = result;
}
extern "C" {
Value conv = oo->getProperty(ctx, meth1);
if (!conv.isUndefined() && conv.isFunctionObject()) {
- Value r;
- __qmljs_call_value(ctx, &r, object, &conv, 0, 0);
+ Value r = __qmljs_call_value(ctx, *object, &conv, 0, 0);
if (r.isPrimitive()) {
*result = r;
return;
conv = oo->getProperty(ctx, meth2);
if (!conv.isUndefined() && conv.isFunctionObject()) {
- Value r;
- __qmljs_call_value(ctx, &r, object, &conv, 0, 0);
+ Value r = __qmljs_call_value(ctx, *object, &conv, 0, 0);
if (r.isPrimitive()) {
*result = r;
return;
context->throwReferenceError(Value::fromString(name));
return Value::undefinedValue();
}
- Value result;
- __qmljs_call_value(context, &result, /*thisObject=*/ 0, func, args, argc);
+ Value result = __qmljs_call_value(context, Value::undefinedValue(), func, args, argc);
return result;
}
-void __qmljs_call_property(Context *context, Value *result, const Value *base, String *name, Value *args, int argc)
+Value __qmljs_call_property(Context *context, const Value base, String *name, Value *args, int argc)
{
Value baseObject;
Value thisObject;
- if (base) {
- baseObject = *base;
+ if (!base.isUndefined()) {
+ baseObject = base;
if (!baseObject.isObject())
__qmljs_to_object(context, &baseObject, &baseObject);
assert(baseObject.isObject());
thisObject = Value::nullValue();
}
Value func = baseObject.property(context, name);
+ Value result;
if (FunctionObject *f = func.asFunctionObject()) {
Context k;
Context *ctx = f->needsActivation ? context->engine->newContext() : &k;
context->hasUncaughtException = ctx->hasUncaughtException; // propagate the exception
context->result = ctx->result;
}
- ctx->leaveCallContext(f, result);
+ ctx->leaveCallContext(f);
+ result = ctx->result;
} else {
context->throwTypeError();
}
+ return result;
}
-void __qmljs_call_value(Context *context, Value *result, const Value *thisObject, const Value *func, Value *args, int argc)
+Value __qmljs_call_value(Context *context, const Value thisObject, const Value *func, Value *args, int argc)
{
+ Value result;
if (FunctionObject *f = func->asFunctionObject()) {
Context k;
Context *ctx = f->needsActivation ? context->engine->newContext() : &k;
- ctx->initCallContext(context->engine, thisObject, f, args, argc);
+ const Value *that = thisObject.isUndefined() ? 0 : &thisObject;
+ ctx->initCallContext(context->engine, that, f, args, argc);
f->call(ctx);
if (ctx->hasUncaughtException) {
context->hasUncaughtException = ctx->hasUncaughtException; // propagate the exception
context->result = ctx->result;
}
- ctx->leaveCallContext(f, result);
+ ctx->leaveCallContext(f);
+ result = ctx->result;
} else {
context->throwTypeError();
}
+ return result;
}
Value __qmljs_construct_activation_property(Context *context, String *name, Value *args, int argc)
// context
Value __qmljs_call_activation_property(Context *, String *name, Value *args, int argc);
-void __qmljs_call_property(Context *context, Value *result, const Value *base, String *name, Value *args, int argc);
-void __qmljs_call_value(Context *context, Value *result, const Value *thisObject, const Value *func, Value *args, int argc);
+Value __qmljs_call_property(Context *context, const Value base, String *name, Value *args, int argc);
+Value __qmljs_call_value(Context *context, const Value thisObject, const Value *func, Value *args, int argc);
Value __qmljs_construct_activation_property(Context *, String *name, Value *args, int argc);
void __qmljs_construct_property(Context *context, Value *result, const Value *base, String *name, Value *args, int argc);
#endif
void initCallContext(ExecutionEngine *e, const Value *object, FunctionObject *f, Value *args, unsigned argc);
- void leaveCallContext(FunctionObject *f, Value *r);
+ void leaveCallContext(FunctionObject *f);
void initConstructorContext(ExecutionEngine *e, const Value *object, FunctionObject *f, Value *args, unsigned argc);
void leaveConstructorContext(FunctionObject *f, Value *returnValue);
return true;
if (!m_comparefn.isUndefined()) {
Value args[] = { v1, v2 };
- Value result;
- __qmljs_call_value(m_context, &result, 0, &m_comparefn, args, 2);
+ Value result = __qmljs_call_value(m_context, Value::undefinedValue(), &m_comparefn, args, 2);
return result.toNumber(m_context) <= 0;
}
return v1.toString(m_context)->toQString() < v2.toString(m_context)->toQString();
args[0] = v;
args[1] = Value::fromDouble(k);
args[2] = ctx->thisObject;
- Value r;
- __qmljs_call_value(ctx, &r, &thisArg, &callback, args, 3);
+ Value r = __qmljs_call_value(ctx, thisArg, &callback, args, 3);
ok = __qmljs_to_boolean(r, ctx);
}
ctx->result = Value::fromBoolean(ok);
args[0] = v;
args[1] = Value::fromDouble(k);
args[2] = ctx->thisObject;
- Value r;
- __qmljs_call_value(ctx, &r, &thisArg, &callback, args, 3);
+ Value r = __qmljs_call_value(ctx, thisArg, &callback, args, 3);
ok = __qmljs_to_boolean(r, ctx);
}
ctx->result = Value::fromBoolean(ok);
Value v = instance->value.at(k);
if (v.isUndefined())
continue;
- Value r;
Value args[3];
args[0] = v;
args[1] = Value::fromDouble(k);
args[2] = ctx->thisObject;
- __qmljs_call_value(ctx, &r, &thisArg, &callback, args, 3);
+ Value r = __qmljs_call_value(ctx, thisArg, &callback, args, 3);
}
}
} else {
Value v = instance->value.at(k);
if (v.isUndefined())
continue;
- Value r;
Value args[3];
args[0] = v;
args[1] = Value::fromDouble(k);
args[2] = ctx->thisObject;
- __qmljs_call_value(ctx, &r, &thisArg, &callback, args, 3);
+ Value r = __qmljs_call_value(ctx, thisArg, &callback, args, 3);
a->value.assign(k, r);
}
ctx->result = Value::fromObject(a);
Value v = instance->value.at(k);
if (v.isUndefined())
continue;
- Value r;
Value args[3];
args[0] = v;
args[1] = Value::fromDouble(k);
args[2] = ctx->thisObject;
- __qmljs_call_value(ctx, &r, &thisArg, &callback, args, 3);
+ Value r = __qmljs_call_value(ctx, thisArg, &callback, args, 3);
if (__qmljs_to_boolean(r, ctx)) {
const uint index = a->value.size();
a->value.resize(index + 1);
continue;
}
- Value r;
Value args[4];
args[0] = acc;
args[1] = v;
args[2] = Value::fromDouble(k);
args[3] = ctx->thisObject;
- __qmljs_call_value(ctx, &r, 0, &callback, args, 4);
+ Value r = __qmljs_call_value(ctx, Value::undefinedValue(), &callback, args, 4);
acc = r;
}
ctx->result = acc;
continue;
}
- Value r;
Value args[4];
args[0] = acc;
args[1] = v;
args[2] = Value::fromDouble(k);
args[3] = ctx->thisObject;
- __qmljs_call_value(ctx, &r, 0, &callback, args, 4);
+ Value r = __qmljs_call_value(ctx, Value::undefinedValue(), &callback, args, 4);
acc = r;
}
ctx->result = acc;
return;
}
- __qmljs_call_value(ctx, &ctx->result, &thisObject, &ctx->thisObject, args.data(), args.size());
+ ctx->result = __qmljs_call_value(ctx, thisObject, &ctx->thisObject, args.data(), args.size());
} else {
ctx->throwTypeError();
}
QVector<Value> args(ctx->argumentCount ? ctx->argumentCount - 1 : 0);
if (ctx->argumentCount)
qCopy(ctx->arguments + 1, ctx->arguments + ctx->argumentCount, args.begin());
- __qmljs_call_value(ctx, &ctx->result, &thisArg, &ctx->thisObject, args.data(), args.size());
+ ctx->result = __qmljs_call_value(ctx, thisArg, &ctx->thisObject, args.data(), args.size());
} else {
ctx->throwTypeError();
}
int argc = prepareVariableArguments(call->args);
IR::Temp* thisObject = 0;
- generateFunctionCall(__qmljs_call_value, ContextRegister, result, baseTemp, thisObject, baseAddressForCallArguments(), TrustedImm32(argc));
+ generateFunctionCall2(result, __qmljs_call_value, ContextRegister, baseTemp, thisObject, baseAddressForCallArguments(), TrustedImm32(argc));
checkExceptions();
}
assert(member->base->asTemp() != 0);
int argc = prepareVariableArguments(call->args);
- IR::Temp* thisObject = 0;
- generateFunctionCall(__qmljs_call_property, ContextRegister, result, member->base->asTemp(), identifier(*member->name), baseAddressForCallArguments(), TrustedImm32(argc));
+ generateFunctionCall2(result, __qmljs_call_property, ContextRegister, member->base->asTemp(), identifier(*member->name), baseAddressForCallArguments(), TrustedImm32(argc));
checkExceptions();
}
assert(member->base->asTemp() != 0);
int argc = prepareVariableArguments(call->args);
- IR::Temp* thisObject = 0;
generateFunctionCall(__qmljs_construct_property, ContextRegister, result, member->base->asTemp(), identifier(*member->name), baseAddressForCallArguments(), TrustedImm32(argc));
checkExceptions();
}
void loadArgument1(IR::Temp* temp, RegisterID dest)
{
- assert(temp);
- Pointer addr = loadTempAddress(dest, temp);
- loadPtr(addr, dest);
+ if (!temp) {
+ VM::Value undefined = VM::Value::undefinedValue();
+ move(TrustedImmPtr((const void *)undefined.val), dest);
+ } else {
+ Pointer addr = loadTempAddress(dest, temp);
+ loadPtr(addr, dest);
+ }
}
void loadArgument1(VM::String* string, RegisterID dest)
callFunctionEpilogue();
}
- template <typename ArgRet, typename Arg1, typename Arg2, typename Arg3>
- void generateFunctionCallImp2(ArgRet r, const char* functionName, FunctionPtr function, Arg1 arg1, Arg2 arg2, Arg3 arg3)
+ template <typename ArgRet, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
+ void generateFunctionCallImp2(ArgRet r, const char* functionName, FunctionPtr function, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4)
{
callFunctionPrologue();
loadArgument1(arg1, RegisterArgument1);
loadArgument1(arg2, RegisterArgument2);
loadArgument1(arg3, RegisterArgument3);
+ loadArgument1(arg4, RegisterArgument4);
callAbsolute(functionName, function);
storeArgument(ReturnValueRegister, r);
callFunctionEpilogue();
}
- template <typename ArgRet, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
- void generateFunctionCallImp2(ArgRet r, const char* functionName, FunctionPtr function, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4)
+ template <typename ArgRet, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
+ void generateFunctionCallImp2(ArgRet r, const char* functionName, FunctionPtr function, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5)
{
callFunctionPrologue();
loadArgument1(arg1, RegisterArgument1);
loadArgument1(arg2, RegisterArgument2);
loadArgument1(arg3, RegisterArgument3);
loadArgument1(arg4, RegisterArgument4);
+ loadArgument1(arg5, RegisterArgument5);
+ callAbsolute(functionName, function);
+ storeArgument(ReturnValueRegister, r);
+ callFunctionEpilogue();
+ }
+
+ template <typename ArgRet, typename Arg1, typename Arg2, typename Arg3>
+ void generateFunctionCallImp2(ArgRet r, const char* functionName, FunctionPtr function, Arg1 arg1, Arg2 arg2, Arg3 arg3)
+ {
+ callFunctionPrologue();
+ loadArgument1(arg1, RegisterArgument1);
+ loadArgument1(arg2, RegisterArgument2);
+ loadArgument1(arg3, RegisterArgument3);
callAbsolute(functionName, function);
storeArgument(ReturnValueRegister, r);
callFunctionEpilogue();