V4IR::BasicBlock *exitBlock = function->newBasicBlock(groupStartBlock(), V4IR::Function::DontInsertBlock);
V4IR::BasicBlock *throwBlock = function->newBasicBlock(groupStartBlock());
function->hasDirectEval = _env->hasDirectEval;
- function->usesArgumentsObject = (_env->usesArgumentsObject == Environment::ArgumentsObjectUsed);
+ function->usesArgumentsObject = _env->parent && (_env->usesArgumentsObject == Environment::ArgumentsObjectUsed);
function->maxNumberOfArguments = _env->maxNumberOfArguments;
function->isStrict = _env->isStrict;
function->isNamedExpression = _env->isNamedFunctionExpression;
+ if (function->usesArgumentsObject)
+ _env->enter("arguments", Environment::VariableDeclaration);
+
// variables in global code are properties of the global context object, not locals as with other functions.
if (_mode == FunctionCode) {
unsigned t = 0;
}
}
}
+ if (_function->usesArgumentsObject) {
+ move(_block->NAME("arguments", ast->firstSourceLocation().startLine, ast->firstSourceLocation().startColumn),
+ _block->CALL(_block->NAME(V4IR::Name::builtin_setup_argument_object,
+ ast->firstSourceLocation().startLine, ast->firstSourceLocation().startColumn), 0));
+ }
sourceElements(body);
F(CallBuiltinDefineProperty, callBuiltinDefineProperty) \
F(CallBuiltinDefineArray, callBuiltinDefineArray) \
F(CallBuiltinDefineObjectLiteral, callBuiltinDefineObjectLiteral) \
+ F(CallBuiltinSetupArgumentsObject, callBuiltinSetupArgumentsObject) \
F(CreateValue, createValue) \
F(CreateProperty, createProperty) \
F(CreateActivationProperty, createActivationProperty) \
quint32 args;
Param result;
};
+ struct instr_callBuiltinSetupArgumentsObject {
+ MOTH_INSTR_HEADER
+ Param result;
+ };
struct instr_createValue {
MOTH_INSTR_HEADER
quint32 argc;
instr_callBuiltinDefineProperty callBuiltinDefineProperty;
instr_callBuiltinDefineArray callBuiltinDefineArray;
instr_callBuiltinDefineObjectLiteral callBuiltinDefineObjectLiteral;
+ instr_callBuiltinSetupArgumentsObject callBuiltinSetupArgumentsObject;
instr_createValue createValue;
instr_createProperty createProperty;
instr_createActivationProperty createActivationProperty;
Assembler::TrustedImmPtr(klass));
}
+void InstructionSelection::callBuiltinSetupArgumentObject(V4IR::Temp *result)
+{
+ generateFunctionCall(Assembler::Void, __qmljs_builtin_setup_arguments_object, Assembler::ContextRegister,
+ Assembler::PointerToValue(result));
+}
+
void InstructionSelection::callValue(V4IR::Temp *value, V4IR::ExprList *args, V4IR::Temp *result)
{
int argc = prepareVariableArguments(args);
virtual void callBuiltinDefineProperty(V4IR::Temp *object, const QString &name, V4IR::Temp *value);
virtual void callBuiltinDefineArray(V4IR::Temp *result, V4IR::ExprList *args);
virtual void callBuiltinDefineObjectLiteral(V4IR::Temp *result, V4IR::ExprList *args);
+ virtual void callBuiltinSetupArgumentObject(V4IR::Temp *result);
virtual void callValue(V4IR::Temp *value, V4IR::ExprList *args, V4IR::Temp *result);
virtual void callProperty(V4IR::Temp *base, const QString &name, V4IR::ExprList *args, V4IR::Temp *result);
virtual void callSubscript(V4IR::Temp *base, V4IR::Temp *index, V4IR::ExprList *args, V4IR::Temp *result);
addInstruction(call);
}
+void InstructionSelection::callBuiltinSetupArgumentObject(V4IR::Temp *result)
+{
+ Instruction::CallBuiltinSetupArgumentsObject call;
+ call.result = getResultParam(result);
+ addInstruction(call);
+}
+
ptrdiff_t InstructionSelection::addInstructionHelper(Instr::Type type, Instr &instr)
{
#ifdef MOTH_THREADED_INTERPRETER
virtual void callBuiltinDefineProperty(V4IR::Temp *object, const QString &name, V4IR::Temp *value);
virtual void callBuiltinDefineArray(V4IR::Temp *result, V4IR::ExprList *args);
virtual void callBuiltinDefineObjectLiteral(V4IR::Temp *result, V4IR::ExprList *args);
+ virtual void callBuiltinSetupArgumentObject(V4IR::Temp *result);
virtual void callValue(V4IR::Temp *value, V4IR::ExprList *args, V4IR::Temp *result);
virtual void callProperty(V4IR::Temp *base, const QString &name, V4IR::ExprList *args, V4IR::Temp *result);
virtual void callSubscript(V4IR::Temp *base, V4IR::Temp *index, V4IR::ExprList *args, V4IR::Temp *result);
callBuiltinDefineObjectLiteral(result, call->args);
return;
+ case V4IR::Name::builtin_setup_argument_object:
+ callBuiltinSetupArgumentObject(result);
+ return;
+
default:
break;
}
virtual void callBuiltinDefineProperty(V4IR::Temp *object, const QString &name, V4IR::Temp *value) = 0;
virtual void callBuiltinDefineArray(V4IR::Temp *result, V4IR::ExprList *args) = 0;
virtual void callBuiltinDefineObjectLiteral(V4IR::Temp *result, V4IR::ExprList *args) = 0;
+ virtual void callBuiltinSetupArgumentObject(V4IR::Temp *result) = 0;
virtual void callValue(V4IR::Temp *value, V4IR::ExprList *args, V4IR::Temp *result) = 0;
virtual void callProperty(V4IR::Temp *base, const QString &name, V4IR::ExprList *args, V4IR::Temp *result) = 0;
virtual void callSubscript(V4IR::Temp *base, V4IR::Temp *index, V4IR::ExprList *args, V4IR::Temp *result) = 0;
return "builtin_define_getter_setter";
case V4IR::Name::builtin_define_object_literal:
return "builtin_define_object_literal";
+ case V4IR::Name::builtin_setup_argument_object:
+ return "builtin_setup_argument_object";
}
return "builtin_(###FIXME)";
};
builtin_define_property,
builtin_define_array,
builtin_define_getter_setter,
- builtin_define_object_literal
+ builtin_define_object_literal,
+ builtin_setup_argument_object
};
const QString *id;
DEFINE_MANAGED_VTABLE(ArgumentsObject);
-ArgumentsObject::ArgumentsObject(CallContext *context, int formalParameterCount, int actualParameterCount)
+ArgumentsObject::ArgumentsObject(CallContext *context)
: Object(context->engine), context(context)
{
vtbl = &static_vtbl;
memberData[CalleePropertyIndex].value = Value::fromObject(context->function);
isNonStrictArgumentsObject = true;
- uint numAccessors = qMin(formalParameterCount, actualParameterCount);
- uint argCount = qMin((uint)actualParameterCount, context->argumentCount);
+ uint numAccessors = qMin(context->function->formalParameterCount, context->realArgumentCount);
+ uint argCount = qMin((uint)context->realArgumentCount, context->argumentCount);
arrayReserve(argCount);
ensureArrayAttributes();
context->engine->requireArgumentsAccessors(numAccessors);
}
assert(LengthPropertyIndex == internalClass->find(context->engine->id_length));
Property *lp = memberData + ArrayObject::LengthPropertyIndex;
- lp->value = Value::fromInt32(actualParameterCount);
+ lp->value = Value::fromInt32(context->realArgumentCount);
}
void ArgumentsObject::destroy(Managed *that)
struct ArgumentsObject: Object {
CallContext *context;
QVector<Value> mappedArguments;
- ArgumentsObject(CallContext *context, int formalParameterCount, int actualParameterCount);
+ ArgumentsObject(CallContext *context);
~ArgumentsObject() {}
enum {
this->function = function;
this->arguments = _arguments;
+ this->realArgumentCount = _argumentCount;
this->argumentCount = _argumentCount;
this->thisObject = _thisObject;
std::fill(arguments + argc, arguments + function->formalParameterCount, Value::undefinedValue());
}
-
- if (function->usesArgumentsObject) {
- ArgumentsObject *args = new (engine->memoryManager) ArgumentsObject(this, function->formalParameterCount, argc);
- args->prototype = engine->objectPrototype;
- activation = engine->newObject();
- Property desc = Property::fromValue(Value::fromObject(args));
- activation->__defineOwnProperty__(this, engine->id_arguments, desc, Attr_NotConfigurable);
- }
}
void CallContext::initQmlContext(ExecutionContext *parentContext, Object *qml, FunctionObject *function)
void initSimpleCallContext(ExecutionEngine *engine);
FunctionObject *function;
Value *arguments;
+ unsigned int realArgumentCount;
unsigned int argumentCount;
};
#include "qv4objectproto_p.h"
#include "qv4globalobject_p.h"
#include "qv4stringobject_p.h"
+#include "qv4argumentsobject_p.h"
#include "qv4lookup_p.h"
#include "qv4function_p.h"
#include "qv4exception_p.h"
*result = Value::fromObject(o);
}
+void __qmljs_builtin_setup_arguments_object(ExecutionContext *ctx, Value *result)
+{
+ assert(ctx->type >= ExecutionContext::Type_CallContext);
+ CallContext *c = static_cast<CallContext *>(ctx);
+ ArgumentsObject *args = new (c->engine->memoryManager) ArgumentsObject(c);
+ args->prototype = c->engine->objectPrototype;
+ *result = Value::fromObject(args);
+}
+
void __qmljs_increment(Value *result, const Value &value)
{
TRACE1(value);
{
return Value::toUInt32(d);
}
+
} // namespace QV4
QT_END_NAMESPACE
void __qmljs_builtin_define_array(QV4::ExecutionContext *ctx, QV4::Value *array, QV4::Value *values, uint length);
void __qmljs_builtin_define_getter_setter(QV4::ExecutionContext *ctx, const QV4::Value &object, QV4::String *name, const QV4::Value *getter, const QV4::Value *setter);
void __qmljs_builtin_define_object_literal(QV4::ExecutionContext *ctx, QV4::Value *result, const QV4::Value *args, QV4::InternalClass *klass);
-
+void __qmljs_builtin_setup_arguments_object(ExecutionContext *ctx, QV4::Value *result);
// constructors
void __qmljs_init_closure(QV4::ExecutionContext *ctx, QV4::Value *result, QV4::Function *clos);
QV4::Function *__qmljs_register_function(QV4::ExecutionContext *ctx, QV4::String *name,
__qmljs_builtin_define_object_literal(context, VALUEPTR(instr.result), args, instr.internalClass);
MOTH_END_INSTR(CallBuiltinDefineObjectLiteral)
+ MOTH_BEGIN_INSTR(CallBuiltinSetupArgumentsObject)
+ __qmljs_builtin_setup_arguments_object(context, VALUEPTR(instr.result));
+ MOTH_END_INSTR(CallBuiltinSetupArgumentsObject)
+
MOTH_BEGIN_INSTR(CreateValue)
Q_ASSERT(instr.args + instr.argc <= stackSize);
QV4::Value *args = stack + instr.args;