return EXIT_FAILURE;
}
- QQmlJS::VM::Function *f = QQmlJS::VM::EvalFunction::parseSource(ctx, fn, code, QQmlJS::Codegen::GlobalCode);
+ QQmlJS::VM::Function *f = QQmlJS::VM::EvalFunction::parseSource(ctx, fn, code, QQmlJS::Codegen::GlobalCode, /*inheritContext =*/ false);
if (!f)
continue;
vm.memoryManager->dumpStats();
} return EXIT_SUCCESS;
- }
+ } // switch (mode)
}
}
locals = function->varCount ? new Value[function->varCount] : 0;
- if (function->varCount)
+ if (locals)
std::fill(locals, locals + function->varCount, Value::undefinedValue());
activation = 0;
{
}
-IR::Function *Codegen::operator()(const QString &fileName, Program *node, IR::Module *module, Mode mode)
+IR::Function *Codegen::operator()(const QString &fileName, Program *node,
+ IR::Module *module, Mode mode,
+ const QStringList &inheritedLocals)
{
assert(node);
ScanFunctions scan(this);
scan(node);
- IR::Function *globalCode = defineFunction(QStringLiteral("%entry"), node, 0, node->elements, mode);
+ IR::Function *globalCode = defineFunction(QStringLiteral("%entry"), node, 0,
+ node->elements, mode, inheritedLocals);
if (_debugger) {
if (node->elements->element) {
SourceLocation loc = node->elements->element->firstSourceLocation();
IR::Function *Codegen::defineFunction(const QString &name, AST::Node *ast,
AST::FormalParameterList *formals,
- AST::SourceElements *body, Mode mode)
+ AST::SourceElements *body, Mode mode,
+ const QStringList &inheritedLocals)
{
qSwap(_mode, mode); // enter function code.
(*it).index = t;
}
} else {
+ if (!_env->isStrict) {
+ foreach (const QString &inheritedLocal, inheritedLocals) {
+ function->LOCAL(inheritedLocal);
+ unsigned tempIndex = entryBlock->newTemp();
+ Environment::Member member = { Environment::UndefinedMember, tempIndex, 0 };
+ _env->members.insert(inheritedLocal, member);
+ }
+ }
+
IR::ExprList *args = 0;
for (Environment::MemberMap::const_iterator it = _env->members.constBegin(); it != _env->members.constEnd(); ++it) {
const QString &local = it.key();
#include "qv4ir_p.h"
#include <private/qqmljsastvisitor_p.h>
+#include <QtCore/QStringList>
#include <assert.h>
namespace QQmlJS {
FunctionCode
};
- IR::Function *operator()(const QString &fileName, AST::Program *ast, IR::Module *module, Mode mode = GlobalCode);
+ IR::Function *operator()(const QString &fileName, AST::Program *ast, IR::Module *module, Mode mode = GlobalCode, const QStringList &inheritedLocals = QStringList());
IR::Function *operator()(const QString &fileName, AST::FunctionExpression *ast, IR::Module *module);
protected:
void cjump(IR::Expr *cond, IR::BasicBlock *iftrue, IR::BasicBlock *iffalse);
void linearize(IR::Function *function);
- IR::Function *defineFunction(const QString &name, AST::Node *ast, AST::FormalParameterList *formals,
- AST::SourceElements *body, Mode mode = FunctionCode);
+ IR::Function *defineFunction(const QString &name, AST::Node *ast,
+ AST::FormalParameterList *formals,
+ AST::SourceElements *body,
+ Mode mode = FunctionCode,
+ const QStringList &inheritedLocals = QStringList());
int indexOfArgument(const QStringRef &string) const;
void unwindException(TryCleanup *outest);
if (argc < 1)
return Value::undefinedValue();
+ ExecutionContext *ctx = context;
+ if (!directCall) {
+ // the context for eval should be the global scope
+ while (ctx->parent)
+ ctx = ctx->parent;
+ }
+
if (!args[0].isString())
return args[0];
const QString code = args[0].stringValue()->toQString();
- QQmlJS::VM::Function *f = parseSource(context, QStringLiteral("eval code"), code, QQmlJS::Codegen::EvalCode);
+ bool inheritContext = !context->strictMode;
+ QQmlJS::VM::Function *f = parseSource(context, QStringLiteral("eval code"),
+ code, QQmlJS::Codegen::EvalCode,
+ inheritContext);
if (!f)
return Value::undefinedValue();
ExecutionContext k;
- ExecutionContext *ctx = context;
- if (!directCall) {
- // the context for eval should be the global scope
- while (ctx->parent)
- ctx = ctx->parent;
- }
-
if (strict) {
ctx = &k;
ctx->initCallContext(context, context->thisObject, this, args, argc);
QQmlJS::VM::Function *EvalFunction::parseSource(QQmlJS::VM::ExecutionContext *ctx,
const QString &fileName, const QString &source,
- QQmlJS::Codegen::Mode mode)
+ QQmlJS::Codegen::Mode mode,
+ bool inheritContext)
{
using namespace QQmlJS;
return 0;
}
+ QStringList inheritedLocals;
+ if (inheritContext)
+ for (String **i = ctx->variables(), **ei = i + ctx->variableCount(); i < ei; ++i)
+ inheritedLocals.append(*i ? (*i)->toQString() : QString());
+
Codegen cg(ctx);
- IR::Function *globalIRCode = cg(fileName, program, &module, mode);
+ IR::Function *globalIRCode = cg(fileName, program, &module, mode, inheritedLocals);
QScopedPointer<EvalInstructionSelection> isel(ctx->engine->iselFactory->create(vm, &module));
if (globalIRCode)
globalCode = isel->vmFunction(globalIRCode);
static QQmlJS::VM::Function *parseSource(QQmlJS::VM::ExecutionContext *ctx,
const QString &fileName,
const QString &source,
- QQmlJS::Codegen::Mode mode);
+ QQmlJS::Codegen::Mode mode,
+ bool inheritContext);
virtual Value call(ExecutionContext *context, Value thisObject, Value *args, int argc);
Value call(ExecutionContext *context, Value thisObject, Value *args, int argc, bool directCall);
11.4.1-2-5 failing
11.4.1-2-6 failing
11.4.1-4.a-5 failing
-11.4.1-4.a-7 failing
11.4.1-5-2 failing
S11.4.1_A1 failing
S11.4.1_A2.1 failing