Fix name lookup for named function expressions
Change-Id: Ia36b2b5c5b40475450fe369c7d6cb5e3965a4488 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
This commit is contained in:
parent
ee7b6a5df5
commit
b5181ea199
|
@ -400,6 +400,11 @@ Value ExecutionContext::getProperty(String *name)
|
|||
if (hasProperty)
|
||||
return v;
|
||||
}
|
||||
if (FunctionObject *f = ctx->function) {
|
||||
if (f->function && f->function->isNamedExpression
|
||||
&& name->isEqualTo(f->function->name))
|
||||
return Value::fromObject(ctx->function);
|
||||
}
|
||||
}
|
||||
throwReferenceError(Value::fromString(name));
|
||||
return Value::undefinedValue();
|
||||
|
@ -446,6 +451,11 @@ Value ExecutionContext::getPropertyNoThrow(String *name)
|
|||
if (hasProperty)
|
||||
return v;
|
||||
}
|
||||
if (FunctionObject *f = ctx->function) {
|
||||
if (f->function && f->function->isNamedExpression
|
||||
&& name->isEqualTo(f->function->name))
|
||||
return Value::fromObject(ctx->function);
|
||||
}
|
||||
}
|
||||
return Value::undefinedValue();
|
||||
}
|
||||
|
@ -494,6 +504,11 @@ Value ExecutionContext::getPropertyAndBase(String *name, Object **base)
|
|||
if (hasProperty)
|
||||
return v;
|
||||
}
|
||||
if (FunctionObject *f = ctx->function) {
|
||||
if (f->function && f->function->isNamedExpression
|
||||
&& name->isEqualTo(f->function->name))
|
||||
return Value::fromObject(ctx->function);
|
||||
}
|
||||
}
|
||||
throwReferenceError(Value::fromString(name));
|
||||
return Value::undefinedValue();
|
||||
|
|
|
@ -404,11 +404,11 @@ protected:
|
|||
return true;
|
||||
}
|
||||
|
||||
void enterFunction(FunctionExpression *ast, bool enterName)
|
||||
void enterFunction(FunctionExpression *ast, bool enterName, bool isExpression = true)
|
||||
{
|
||||
if (_env->isStrict && (ast->name == QLatin1String("eval") || ast->name == QLatin1String("arguments")))
|
||||
_cg->throwSyntaxError(ast->identifierToken, QCoreApplication::translate("qv4codegen", "Function name may not be eval or arguments in strict mode"));
|
||||
enterFunction(ast, ast->name.toString(), ast->formals, ast->body, enterName ? ast : 0);
|
||||
enterFunction(ast, ast->name.toString(), ast->formals, ast->body, enterName ? ast : 0, isExpression);
|
||||
}
|
||||
|
||||
virtual void endVisit(FunctionExpression *)
|
||||
|
@ -418,7 +418,7 @@ protected:
|
|||
|
||||
virtual bool visit(PropertyGetterSetter *ast)
|
||||
{
|
||||
enterFunction(ast, QString(), ast->formals, ast->functionBody);
|
||||
enterFunction(ast, QString(), ast->formals, ast->functionBody, /*FunctionExpression*/0, /*isExpression*/false);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -429,7 +429,7 @@ protected:
|
|||
|
||||
virtual bool visit(FunctionDeclaration *ast)
|
||||
{
|
||||
enterFunction(ast, /*enterName*/ true);
|
||||
enterFunction(ast, /*enterName*/ true, /*isExpression */false);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -449,7 +449,7 @@ protected:
|
|||
}
|
||||
|
||||
private:
|
||||
void enterFunction(Node *ast, const QString &name, FormalParameterList *formals, FunctionBody *body, FunctionExpression *expr = 0)
|
||||
void enterFunction(Node *ast, const QString &name, FormalParameterList *formals, FunctionBody *body, FunctionExpression *expr, bool isExpression)
|
||||
{
|
||||
bool wasStrict = false;
|
||||
if (_env) {
|
||||
|
@ -463,6 +463,8 @@ private:
|
|||
enterEnvironment(ast);
|
||||
checkForArguments(formals);
|
||||
|
||||
_env->isNamedFunctionExpression = isExpression && !name.isEmpty();
|
||||
|
||||
if (body)
|
||||
checkDirectivePrologue(body->elements);
|
||||
|
||||
|
@ -1977,6 +1979,7 @@ IR::Function *Codegen::defineFunction(const QString &name, AST::Node *ast,
|
|||
function->usesArgumentsObject = (_env->usesArgumentsObject == Environment::ArgumentsObjectUsed);
|
||||
function->maxNumberOfArguments = _env->maxNumberOfArguments;
|
||||
function->isStrict = _env->isStrict;
|
||||
function->isNamedExpression = _env->isNamedFunctionExpression;
|
||||
|
||||
// variables in global code are properties of the global context object, not locals as with other functions.
|
||||
if (_mode == FunctionCode) {
|
||||
|
|
|
@ -140,6 +140,7 @@ protected:
|
|||
bool hasDirectEval;
|
||||
bool hasNestedFunctions;
|
||||
bool isStrict;
|
||||
bool isNamedFunctionExpression;
|
||||
enum UsesArgumentsObject {
|
||||
ArgumentsObjectUnknown,
|
||||
ArgumentsObjectNotUsed,
|
||||
|
@ -154,6 +155,7 @@ protected:
|
|||
, hasDirectEval(false)
|
||||
, hasNestedFunctions(false)
|
||||
, isStrict(false)
|
||||
, isNamedFunctionExpression(false)
|
||||
, usesArgumentsObject(ArgumentsObjectUnknown)
|
||||
{
|
||||
if (parent && parent->isStrict)
|
||||
|
|
|
@ -131,6 +131,7 @@ struct Function {
|
|||
bool hasDirectEval;
|
||||
bool usesArgumentsObject;
|
||||
bool isStrict;
|
||||
bool isNamedExpression;
|
||||
|
||||
Function(String *name)
|
||||
: name(name)
|
||||
|
@ -143,6 +144,7 @@ struct Function {
|
|||
, hasDirectEval(false)
|
||||
, usesArgumentsObject(false)
|
||||
, isStrict(false)
|
||||
, isNamedExpression(false)
|
||||
{}
|
||||
~Function();
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ VM::Function *EvalInstructionSelection::createFunctionMapping(VM::Function *oute
|
|||
vmFunction->hasNestedFunctions = !irFunction->nestedFunctions.isEmpty();
|
||||
vmFunction->isStrict = irFunction->isStrict;
|
||||
vmFunction->outer = outer;
|
||||
vmFunction->isNamedExpression = irFunction->isNamedExpression;
|
||||
|
||||
if (outer)
|
||||
outer->nestedFunctions.append(vmFunction);
|
||||
|
|
|
@ -654,7 +654,8 @@ struct Function {
|
|||
uint hasDirectEval: 1;
|
||||
uint usesArgumentsObject : 1;
|
||||
uint isStrict: 1;
|
||||
uint unused : 29;
|
||||
uint isNamedExpression : 1;
|
||||
uint unused : 28;
|
||||
|
||||
template <typename _Tp> _Tp *New() { return new (pool->allocate(sizeof(_Tp))) _Tp(); }
|
||||
|
||||
|
@ -668,6 +669,7 @@ struct Function {
|
|||
, hasDirectEval(false)
|
||||
, usesArgumentsObject(false)
|
||||
, isStrict(false)
|
||||
, isNamedExpression(false)
|
||||
, unused(0)
|
||||
{ this->name = newString(name); }
|
||||
|
||||
|
|
|
@ -11,9 +11,7 @@
|
|||
S11.5.3_A4_T2 failing
|
||||
S11.8.6_A5_T2 failing
|
||||
S13_A15_T4 failing
|
||||
S13_A3_T1 failing
|
||||
S13.2.3_A1 failing
|
||||
S14_A2 failing
|
||||
14.1-5-s failing
|
||||
15.4.4.14-9-a-10 failing
|
||||
15.4.4.14-9-a-17 failing
|
||||
|
@ -43,4 +41,4 @@ S15.2.4.4_A14 failing
|
|||
|
||||
# Function declaration inside if / while
|
||||
Sbp_12.5_A9_T3 failing
|
||||
Sbp_12.6.2_A13_T3 failing
|
||||
Sbp_12.6.2_A13_T3 failing
|
Loading…
Reference in New Issue