mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-20 22:27:31 +09:00
636635 - Do not create named lambda binding for a function created by Function constructor.
This commit is contained in:
parent
dd359c6105
commit
7f7b0a029c
5 changed files with 85 additions and 13 deletions
|
|
@ -2173,7 +2173,7 @@ Parser<ParseHandler>::declareDotGeneratorName()
|
|||
|
||||
template <typename ParseHandler>
|
||||
bool
|
||||
Parser<ParseHandler>::finishFunctionScopes()
|
||||
Parser<ParseHandler>::finishFunctionScopes(bool isStandaloneFunction)
|
||||
{
|
||||
FunctionBox* funbox = pc->functionBox();
|
||||
|
||||
|
|
@ -2182,7 +2182,7 @@ Parser<ParseHandler>::finishFunctionScopes()
|
|||
return false;
|
||||
}
|
||||
|
||||
if (funbox->function()->isNamedLambda()) {
|
||||
if (funbox->function()->isNamedLambda() && !isStandaloneFunction) {
|
||||
if (!propagateFreeNamesAndMarkClosedOverBindings(pc->namedLambdaScope()))
|
||||
return false;
|
||||
}
|
||||
|
|
@ -2192,9 +2192,9 @@ Parser<ParseHandler>::finishFunctionScopes()
|
|||
|
||||
template <>
|
||||
bool
|
||||
Parser<FullParseHandler>::finishFunction()
|
||||
Parser<FullParseHandler>::finishFunction(bool isStandaloneFunction /* = false */)
|
||||
{
|
||||
if (!finishFunctionScopes())
|
||||
if (!finishFunctionScopes(isStandaloneFunction))
|
||||
return false;
|
||||
|
||||
FunctionBox* funbox = pc->functionBox();
|
||||
|
|
@ -2215,7 +2215,7 @@ Parser<FullParseHandler>::finishFunction()
|
|||
funbox->functionScopeBindings().set(*bindings);
|
||||
}
|
||||
|
||||
if (funbox->function()->isNamedLambda()) {
|
||||
if (funbox->function()->isNamedLambda() && !isStandaloneFunction) {
|
||||
Maybe<LexicalScope::Data*> bindings = newLexicalScopeData(pc->namedLambdaScope());
|
||||
if (!bindings)
|
||||
return false;
|
||||
|
|
@ -2227,14 +2227,14 @@ Parser<FullParseHandler>::finishFunction()
|
|||
|
||||
template <>
|
||||
bool
|
||||
Parser<SyntaxParseHandler>::finishFunction()
|
||||
Parser<SyntaxParseHandler>::finishFunction(bool isStandaloneFunction /* = false */)
|
||||
{
|
||||
// The LazyScript for a lazily parsed function needs to know its set of
|
||||
// free variables and inner functions so that when it is fully parsed, we
|
||||
// can skip over any already syntax parsed inner functions and still
|
||||
// retain correct scope information.
|
||||
|
||||
if (!finishFunctionScopes())
|
||||
if (!finishFunctionScopes(isStandaloneFunction))
|
||||
return false;
|
||||
|
||||
// There are too many bindings or inner functions to be saved into the
|
||||
|
|
@ -2354,7 +2354,7 @@ Parser<FullParseHandler>::standaloneFunction(HandleFunction fun,
|
|||
YieldHandling yieldHandling = GetYieldHandling(generatorKind, asyncKind);
|
||||
AutoAwaitIsKeyword awaitIsKeyword(&tokenStream, asyncKind == AsyncFunction);
|
||||
if (!functionFormalParametersAndBody(InAllowed, yieldHandling, fn, Statement,
|
||||
parameterListEnd))
|
||||
parameterListEnd, /* isStandaloneFunction = */ true))
|
||||
{
|
||||
return null();
|
||||
}
|
||||
|
|
@ -3425,7 +3425,8 @@ bool
|
|||
Parser<ParseHandler>::functionFormalParametersAndBody(InHandling inHandling,
|
||||
YieldHandling yieldHandling,
|
||||
Node pn, FunctionSyntaxKind kind,
|
||||
Maybe<uint32_t> parameterListEnd /* = Nothing() */)
|
||||
Maybe<uint32_t> parameterListEnd /* = Nothing() */,
|
||||
bool isStandaloneFunction /* = false */)
|
||||
{
|
||||
// Given a properly initialized parse context, try to parse an actual
|
||||
// function without concern for conversion to strict mode, use of lazy
|
||||
|
|
@ -3533,7 +3534,7 @@ Parser<ParseHandler>::functionFormalParametersAndBody(InHandling inHandling,
|
|||
if (IsMethodDefinitionKind(kind) && pc->superScopeNeedsHomeObject())
|
||||
funbox->setNeedsHomeObject();
|
||||
|
||||
if (!finishFunction())
|
||||
if (!finishFunction(isStandaloneFunction))
|
||||
return false;
|
||||
|
||||
handler.setEndPosition(body, pos().begin);
|
||||
|
|
|
|||
|
|
@ -1070,7 +1070,8 @@ class Parser final : private JS::AutoGCRooter, public StrictModeGetter
|
|||
// ParseContext is already on the stack.
|
||||
bool functionFormalParametersAndBody(InHandling inHandling, YieldHandling yieldHandling,
|
||||
Node pn, FunctionSyntaxKind kind,
|
||||
mozilla::Maybe<uint32_t> parameterListEnd = mozilla::Nothing());
|
||||
mozilla::Maybe<uint32_t> parameterListEnd = mozilla::Nothing(),
|
||||
bool isStandaloneFunction = false);
|
||||
|
||||
|
||||
// Determine whether |yield| is a valid name in the current context, or
|
||||
|
|
@ -1350,8 +1351,8 @@ class Parser final : private JS::AutoGCRooter, public StrictModeGetter
|
|||
GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
|
||||
bool tryAnnexB,
|
||||
Directives inheritedDirectives, Directives* newDirectives);
|
||||
bool finishFunctionScopes();
|
||||
bool finishFunction();
|
||||
bool finishFunctionScopes(bool isStandaloneFunction);
|
||||
bool finishFunction(bool isStandaloneFunction = false);
|
||||
bool leaveInnerFunction(ParseContext* outerpc);
|
||||
|
||||
bool matchOrInsertSemicolonHelper(TokenStream::Modifier modifier);
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ UNIFIED_SOURCES += [
|
|||
'testForOfIterator.cpp',
|
||||
'testForwardSetProperty.cpp',
|
||||
'testFreshGlobalEvalRedefinition.cpp',
|
||||
'testFunctionBinding.cpp',
|
||||
'testFunctionProperties.cpp',
|
||||
'testGCAllocator.cpp',
|
||||
'testGCCellPtr.cpp',
|
||||
|
|
|
|||
58
js/src/jsapi-tests/testFunctionBinding.cpp
Normal file
58
js/src/jsapi-tests/testFunctionBinding.cpp
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
||||
*
|
||||
* Test function name binding.
|
||||
*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "jsfriendapi.h"
|
||||
|
||||
#include "jsapi-tests/tests.h"
|
||||
|
||||
using namespace js;
|
||||
|
||||
BEGIN_TEST(test_functionBinding)
|
||||
{
|
||||
RootedFunction fun(cx);
|
||||
|
||||
JS::CompileOptions options(cx);
|
||||
options.setFileAndLine(__FILE__, __LINE__);
|
||||
|
||||
// Named function shouldn't have it's binding.
|
||||
const char s1chars[] = "return (typeof s1) == 'undefined';";
|
||||
JS::AutoObjectVector emptyScopeChain(cx);
|
||||
CHECK(JS::CompileFunction(cx, emptyScopeChain, options, "s1", 0, nullptr, s1chars,
|
||||
strlen(s1chars), &fun));
|
||||
CHECK(fun);
|
||||
|
||||
JS::AutoValueVector args(cx);
|
||||
RootedValue rval(cx);
|
||||
CHECK(JS::Call(cx, UndefinedHandleValue, fun, args, &rval));
|
||||
CHECK(rval.isBoolean());
|
||||
CHECK(rval.toBoolean());
|
||||
|
||||
// Named function shouldn't have `anonymous` binding.
|
||||
const char s2chars[] = "return (typeof anonymous) == 'undefined';";
|
||||
CHECK(JS::CompileFunction(cx, emptyScopeChain, options, "s2", 0, nullptr, s2chars,
|
||||
strlen(s2chars), &fun));
|
||||
CHECK(fun);
|
||||
|
||||
CHECK(JS::Call(cx, UndefinedHandleValue, fun, args, &rval));
|
||||
CHECK(rval.isBoolean());
|
||||
CHECK(rval.toBoolean());
|
||||
|
||||
// Anonymous function shouldn't have `anonymous` binding.
|
||||
const char s3chars[] = "return (typeof anonymous) == 'undefined';";
|
||||
CHECK(JS::CompileFunction(cx, emptyScopeChain, options, nullptr, 0, nullptr, s3chars,
|
||||
strlen(s3chars), &fun));
|
||||
CHECK(fun);
|
||||
|
||||
CHECK(JS::Call(cx, UndefinedHandleValue, fun, args, &rval));
|
||||
CHECK(rval.isBoolean());
|
||||
CHECK(rval.toBoolean());
|
||||
|
||||
return true;
|
||||
}
|
||||
END_TEST(test_functionBinding)
|
||||
11
js/src/tests/ecma_6/Function/constructor-binding.js
Normal file
11
js/src/tests/ecma_6/Function/constructor-binding.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
var BUGNUMBER = 636635;
|
||||
var summary = "A function created by Function constructor shouldn't have anonymous binding";
|
||||
|
||||
print(BUGNUMBER + ": " + summary);
|
||||
|
||||
assertEq(new Function("return typeof anonymous")(), "undefined");
|
||||
assertEq(new Function("return function() { return typeof anonymous; }")()(), "undefined");
|
||||
assertEq(new Function("return function() { eval(''); return typeof anonymous; }")()(), "undefined");
|
||||
|
||||
if (typeof reportCompare === "function")
|
||||
reportCompare(true, true);
|
||||
Loading…
Add table
Add a link
Reference in a new issue