EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_object)
EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_spread_arrays)
EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_sharedarraybuffer)
-EMPTY_NATIVE_FUNCTIONS_FOR_FEATURE(harmony_default_parameters)
void Genesis::InstallNativeFunctions_harmony_proxies() {
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_destructuring)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_object)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_spread_arrays)
-EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_default_parameters)
void Genesis::InitializeGlobal_harmony_regexps() {
Handle<JSObject> builtins(native_context()->builtins());
static const char* harmony_spread_arrays_natives[] = {nullptr};
static const char* harmony_sharedarraybuffer_natives[] = {
"native harmony-sharedarraybuffer.js", NULL};
- static const char* harmony_default_parameters_natives[] = {nullptr};
for (int i = ExperimentalNatives::GetDebuggerCount();
i < ExperimentalNatives::GetBuiltinsCount(); i++) {
V(harmony_reflect, "harmony Reflect API") \
V(harmony_destructuring, "harmony destructuring") \
V(harmony_spread_arrays, "harmony spread in array literals") \
- V(harmony_sharedarraybuffer, "harmony sharedarraybuffer") \
- V(harmony_default_parameters, "harmony default parameters")
+ V(harmony_sharedarraybuffer, "harmony sharedarraybuffer")
// Features that are complete (but still behind --harmony/es-staging flag).
#define HARMONY_STAGED(V) \
T(ParamAfterRest, "Rest parameter must be last formal parameter") \
T(BadSetterRestParameter, \
"Setter function argument must not be a rest parameter") \
- T(BadRestParameterInitializer, \
- "Rest parameters must not have an initializer") \
T(ParenthesisInArgString, "Function arg string contains parenthesis") \
T(SingleFunctionLiteral, "Single function literal required") \
T(SloppyLexical, \
set_allow_harmony_spreadcalls(FLAG_harmony_spreadcalls);
set_allow_harmony_destructuring(FLAG_harmony_destructuring);
set_allow_harmony_spread_arrays(FLAG_harmony_spread_arrays);
- set_allow_harmony_default_parameters(FLAG_harmony_default_parameters);
set_allow_strong_mode(FLAG_strong_mode);
for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
++feature) {
scope->set_start_position(shared_info->start_position());
ExpressionClassifier formals_classifier;
bool has_rest = false;
- bool has_parameter_expressions = false;
-
- // TODO(caitp): make default parameters work in arrow functions
- ZoneList<Expression*>* initializers =
- new (zone()) ZoneList<Expression*>(0, zone());
if (Check(Token::LPAREN)) {
// '(' StrictFormalParameters ')'
- ParseFormalParameterList(scope, initializers,
- &has_parameter_expressions, &has_rest,
- &formals_classifier, &ok);
+ ParseFormalParameterList(scope, &has_rest, &formals_classifier, &ok);
if (ok) ok = Check(Token::RPAREN);
} else {
// BindingIdentifier
}
-ZoneList<Statement*>* Parser::DesugarInitializeParameters(
- Scope* scope, bool has_parameter_expressions,
- ZoneList<Expression*>* initializers) {
- DCHECK(scope->is_function_scope());
-
- if (has_parameter_expressions) {
- // If has_parameter_expressions for the function is true, each parameter is
- // desugared as follows:
- //
- // SingleNameBinding :
- // let <name> = %_Arguments(<index>);
- // SingleNameBinding Initializer
- // let <name> = IS_UNDEFINED(%_Arguments(<index>)) ? <initializer>
- // : %_Arguments(<index>);
- //
- // TODO(caitp, dslomov): support BindingPatterns & rest parameters
- //
- scope->UndeclareParametersForExpressions();
- ZoneList<Statement*>* body =
- new (zone()) ZoneList<Statement*>(initializers->length(), zone());
- for (int i = 0; i < initializers->length(); ++i) {
- Expression* initializer = initializers->at(i);
-
- // Position of parameter VariableProxy, for hole-checking
- int pos = scope->parameter_position(i);
-
- static const int kCapacity = 1;
- static const bool kIsInitializerBlock = true;
- Block* param_block =
- factory()->NewBlock(nullptr, kCapacity, kIsInitializerBlock, pos);
-
- VariableProxy* proxy =
- NewUnresolved(scope->parameter(i)->raw_name(), LET);
- VariableDeclaration* declaration = factory()->NewVariableDeclaration(
- proxy, LET, scope, RelocInfo::kNoPosition);
-
- bool ok = true;
- // All formal parameters have been removed from the scope VariableMap,
- // and so Declare() should not be able to fail.
- proxy = factory()->NewVariableProxy(Declare(declaration, true, &ok), pos);
- DCHECK(ok);
-
- const AstRawString* fn_name = ast_value_factory()->empty_string();
- const Runtime::Function* arguments =
- Runtime::FunctionForId(Runtime::kInlineArguments);
- ZoneList<Expression*>* arguments_i0 =
- new (zone()) ZoneList<Expression*>(1, zone());
- arguments_i0->Add(factory()->NewSmiLiteral(i, RelocInfo::kNoPosition),
- zone());
-
- if (initializer == nullptr) {
- // let <name> = %_Arguments(i)
- Expression* assign = factory()->NewAssignment(
- Token::INIT_LET, proxy,
- factory()->NewCallRuntime(fn_name, arguments, arguments_i0,
- RelocInfo::kNoPosition),
- RelocInfo::kNoPosition);
- param_block->AddStatement(
- factory()->NewExpressionStatement(assign, RelocInfo::kNoPosition),
- zone());
- proxy->var()->set_initializer_position(pos);
- } else {
- // IS_UNDEFINED(%_Arguments(i)) ? <initializer> : %_Arguments(i);
- ZoneList<Expression*>* arguments_i1 =
- new (zone()) ZoneList<Expression*>(1, zone());
- arguments_i1->Add(factory()->NewSmiLiteral(i, RelocInfo::kNoPosition),
- zone());
-
- Expression* arg_or_default = factory()->NewConditional(
- // condition:
- factory()->NewCompareOperation(
- Token::EQ_STRICT,
- factory()->NewCallRuntime(fn_name, arguments, arguments_i0,
- RelocInfo::kNoPosition),
- factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
- RelocInfo::kNoPosition),
- // if true:
- initializer,
- // if false:
- factory()->NewCallRuntime(fn_name, arguments, arguments_i1,
- RelocInfo::kNoPosition),
- RelocInfo::kNoPosition);
-
- Expression* assign = factory()->NewAssignment(
- Token::INIT_LET, proxy, arg_or_default, RelocInfo::kNoPosition);
-
- param_block->AddStatement(
- factory()->NewExpressionStatement(assign, RelocInfo::kNoPosition),
- zone());
- proxy->var()->set_initializer_position(initializer->position());
- }
- body->Add(param_block, zone());
- }
- return body;
- } else {
- // If has_parameter_expressions is false, remove the unnecessary parameter
- // block scopes.
- ZoneList<Scope*>* scopes = scope->inner_scopes();
- for (int i = 0; i < scopes->length(); ++i) {
- Scope* scope = scopes->at(i);
- DCHECK(scope->is_block_scope());
- scope->FinalizeBlockScope();
- }
- return nullptr;
- }
-}
-
-
Statement* Parser::ParseForStatement(ZoneList<const AstRawString*>* labels,
bool* ok) {
// ForStatement ::
parser_->scope_->RemoveUnresolved(expr->AsVariableProxy());
bool is_rest = false;
- int pos = expr->position();
- bool is_duplicate = DeclareFormalParameter(scope, raw_name, is_rest, pos);
+ bool is_duplicate = DeclareFormalParameter(scope, raw_name, is_rest);
if (is_duplicate && !duplicate_loc->IsValid()) {
*duplicate_loc = param_location;
}
bool has_rest = false;
- bool has_parameter_expressions = false;
Expect(Token::LPAREN, CHECK_OK);
int start_position = scanner()->location().beg_pos;
scope_->set_start_position(start_position);
- ZoneList<Expression*>* initializers =
- new (zone()) ZoneList<Expression*>(0, zone());
- num_parameters = ParseFormalParameterList(
- scope, initializers, &has_parameter_expressions, &has_rest,
- &formals_classifier, CHECK_OK);
+ num_parameters = ParseFormalParameterList(scope, &has_rest,
+ &formals_classifier, CHECK_OK);
Expect(Token::RPAREN, CHECK_OK);
int formals_end_position = scanner()->location().end_pos;
}
}
if (!is_lazily_parsed) {
- body = DesugarInitializeParameters(scope, has_parameter_expressions,
- initializers);
- if (has_parameter_expressions) {
- // TODO(caitp): Function body scope must be a declaration scope
- Scope* function_body_scope = NewScope(scope, BLOCK_SCOPE);
- function_body_scope->set_start_position(scope->start_position());
- function_body_scope->SetScopeName(function_name);
- BlockState function_body_state(&scope_, function_body_scope);
- ZoneList<Statement*>* inner_body = ParseEagerFunctionBody(
- function_name, pos, fvar, fvar_init_op, kind, CHECK_OK);
-
- // Declare Block node
- Block* block =
- factory()->NewBlock(nullptr, inner_body->length(), false, pos);
- block->set_scope(function_body_scope);
- for (int i = 0; i < inner_body->length(); ++i) {
- block->AddStatement(inner_body->at(i), zone());
- }
-
- scope->set_end_position(function_body_scope->end_position());
- body->Add(block, zone());
- } else {
- body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op,
- kind, CHECK_OK);
- }
+ body = ParseEagerFunctionBody(function_name, pos, fvar, fvar_init_op,
+ kind, CHECK_OK);
materialized_literal_count = function_state.materialized_literal_count();
expected_property_count = function_state.expected_property_count();
handler_count = function_state.handler_count();
allow_harmony_destructuring());
reusable_preparser_->set_allow_harmony_spread_arrays(
allow_harmony_spread_arrays());
- reusable_preparser_->set_allow_harmony_default_parameters(
- allow_harmony_default_parameters());
reusable_preparser_->set_allow_strong_mode(allow_strong_mode());
}
PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction(
FunctionKind kind = kNormalFunction);
bool DeclareFormalParameter(Scope* scope, const AstRawString* name,
- bool is_rest, int pos) {
+ bool is_rest) {
bool is_duplicate = false;
- Variable* var =
- scope->DeclareParameter(name, VAR, is_rest, &is_duplicate, pos);
+ Variable* var = scope->DeclareParameter(name, VAR, is_rest, &is_duplicate);
if (is_sloppy(scope->language_mode())) {
// TODO(sigurds) Mark every parameter as maybe assigned. This is a
// conservative approximation necessary to account for parameters
bool* ok_;
};
+
void ParseVariableDeclarations(VariableDeclarationContext var_context,
DeclarationParsingResult* parsing_result,
bool* ok);
ForStatement* loop, Statement* init, Expression* cond, Statement* next,
Statement* body, bool* ok);
- ZoneList<Statement*>* DesugarInitializeParameters(
- Scope* scope, bool has_parameter_expressions,
- ZoneList<Expression*>* initializers);
-
FunctionLiteral* ParseFunctionLiteral(
const AstRawString* name, Scanner::Location function_name_location,
bool name_is_strict_reserved, FunctionKind kind,
ExpressionClassifier formals_classifier;
bool has_rest = false;
- bool has_parameter_expressions = false;
- PreParserExpressionList initializers = NewExpressionList(0, zone());
Expect(Token::LPAREN, CHECK_OK);
int start_position = scanner()->location().beg_pos;
function_scope->set_start_position(start_position);
int num_parameters;
{
DuplicateFinder duplicate_finder(scanner()->unicode_cache());
- num_parameters = ParseFormalParameterList(
- &duplicate_finder, initializers, &has_parameter_expressions, &has_rest,
- &formals_classifier, CHECK_OK);
+ num_parameters = ParseFormalParameterList(&duplicate_finder, &has_rest,
+ &formals_classifier, CHECK_OK);
}
Expect(Token::RPAREN, CHECK_OK);
int formals_end_position = scanner()->location().end_pos;
public:
// Shorten type names defined by Traits.
typedef typename Traits::Type::Expression ExpressionT;
- typedef typename Traits::Type::ExpressionList ExpressionListT;
typedef typename Traits::Type::Identifier IdentifierT;
typedef typename Traits::Type::FormalParameter FormalParameterT;
typedef typename Traits::Type::FormalParameterScope FormalParameterScopeT;
allow_harmony_computed_property_names_(false),
allow_harmony_rest_params_(false),
allow_harmony_spreadcalls_(false),
- allow_harmony_default_parameters_(false),
allow_strong_mode_(false) {}
// Getters that indicate whether certain syntactical constructs are
bool allow_harmony_spread_arrays() const {
return allow_harmony_spread_arrays_;
}
- bool allow_harmony_default_parameters() const {
- return allow_harmony_default_parameters_;
- }
bool allow_strong_mode() const { return allow_strong_mode_; }
void set_allow_harmony_spread_arrays(bool allow) {
allow_harmony_spread_arrays_ = allow;
}
- void set_allow_harmony_default_parameters(bool allow) {
- allow_harmony_default_parameters_ = allow;
- }
-
protected:
enum AllowRestrictedIdentifiers {
void ParseFormalParameter(FormalParameterScopeT* scope, bool is_rest,
ExpressionClassifier* classifier, bool* ok);
- int ParseFormalParameterList(FormalParameterScopeT* scope,
- ExpressionListT initializers,
- bool* has_parameter_expressions, bool* has_rest,
+ int ParseFormalParameterList(FormalParameterScopeT* scope, bool* has_rest,
ExpressionClassifier* classifier, bool* ok);
void CheckArityRestrictions(
int param_count, FunctionLiteral::ArityRestriction arity_restriction,
bool allow_harmony_spreadcalls_;
bool allow_harmony_destructuring_;
bool allow_harmony_spread_arrays_;
- bool allow_harmony_default_parameters_;
bool allow_strong_mode_;
};
}
V8_INLINE bool DeclareFormalParameter(DuplicateFinder* scope,
- PreParserIdentifier param, bool is_rest,
- int pos);
+ PreParserIdentifier param,
+ bool is_rest);
void CheckConflictingVarDeclarations(Scope* scope, bool* ok) {}
bool PreParserTraits::DeclareFormalParameter(
DuplicateFinder* duplicate_finder, PreParserIdentifier current_identifier,
- bool is_rest, int pos) {
+ bool is_rest) {
return pre_parser_->scanner()->FindSymbol(duplicate_finder, 1) != 0;
}
bool* ok) {
// FormalParameter[Yield,GeneratorParameter] :
// BindingElement[?Yield, ?GeneratorParameter]
- int pos = peek_position();
IdentifierT name = ParseAndClassifyIdentifier(classifier, ok);
if (!*ok) return;
- bool was_declared = Traits::DeclareFormalParameter(scope, name, is_rest, pos);
+ bool was_declared = Traits::DeclareFormalParameter(scope, name, is_rest);
if (was_declared) {
classifier->RecordDuplicateFormalParameterError(scanner()->location());
}
template <class Traits>
int ParserBase<Traits>::ParseFormalParameterList(
- FormalParameterScopeT* scope, ExpressionListT initializers,
- bool* has_parameter_expressions, bool* is_rest,
+ FormalParameterScopeT* scope, bool* is_rest,
ExpressionClassifier* classifier, bool* ok) {
// FormalParameters[Yield,GeneratorParameter] :
// [empty]
if (peek() != Token::RPAREN) {
do {
- Scope* param_scope = NewScope(scope_, BLOCK_SCOPE);
- BlockState param_state(&scope_, param_scope);
- param_scope->set_start_position(peek_position());
if (++parameter_count > Code::kMaxArguments) {
ReportMessage(MessageTemplate::kTooManyParameters);
*ok = false;
return -1;
}
-
- int start_pos = peek_position();
*is_rest = allow_harmony_rest_params() && Check(Token::ELLIPSIS);
ParseFormalParameter(scope, *is_rest, classifier, ok);
if (!*ok) return -1;
-
- // TODO(caitp, dslomov): set *has_parameter_expressions to true if
- // formal parameter is an ObjectBindingPattern containing computed
- // property keys
-
- ExpressionT initializer = this->EmptyExpression();
- if (allow_harmony_default_parameters() && Check(Token::ASSIGN)) {
- // Default parameter initializer
- static const bool accept_IN = true;
- ExpressionClassifier classifier;
- initializer = ParseAssignmentExpression(accept_IN, &classifier, ok);
- if (!*ok) return -1;
- *has_parameter_expressions = true;
-
- // A rest parameter cannot be initialized.
- if (*is_rest) {
- Scanner::Location loc(start_pos, scanner()->location().end_pos);
- ReportMessageAt(loc, MessageTemplate::kBadRestParameterInitializer);
- *ok = false;
- return -1;
- }
- }
- param_scope->set_end_position(scanner()->location().end_pos);
- initializers->Add(initializer, zone());
} while (!*is_rest && Check(Token::COMMA));
if (*is_rest && peek() == Token::COMMA) {
internals_(4, zone),
temps_(4, zone),
params_(4, zone),
- param_positions_(4, zone),
unresolved_(16, zone),
decls_(4, zone),
module_descriptor_(
internals_(4, zone),
temps_(4, zone),
params_(4, zone),
- param_positions_(4, zone),
unresolved_(16, zone),
decls_(4, zone),
module_descriptor_(NULL),
internals_(0, zone),
temps_(0, zone),
params_(0, zone),
- param_positions_(0, zone),
unresolved_(0, zone),
decls_(0, zone),
module_descriptor_(NULL),
module_var_ = NULL,
rest_parameter_ = NULL;
rest_index_ = -1;
- has_parameter_expressions_ = false;
scope_info_ = scope_info;
start_position_ = RelocInfo::kNoPosition;
end_position_ = RelocInfo::kNoPosition;
Variable* Scope::DeclareParameter(const AstRawString* name, VariableMode mode,
- bool is_rest, bool* is_duplicate, int pos) {
+ bool is_rest, bool* is_duplicate) {
DCHECK(!already_resolved());
DCHECK(is_function_scope());
Variable* var = variables_.Declare(this, name, mode, Variable::NORMAL,
// TODO(wingo): Avoid O(n^2) check.
*is_duplicate = IsDeclaredParameter(name);
params_.Add(var, zone());
- param_positions_.Add(pos, zone());
return var;
}
}
-void Scope::UndeclareParametersForExpressions() {
- DCHECK(is_function_scope());
- DCHECK(!has_parameter_expressions_);
- has_parameter_expressions_ = true;
- for (int i = 0; i < num_parameters(); ++i) {
- Variable* p = parameter(i);
- const AstRawString* name = p->raw_name();
- variables_.Remove(const_cast<AstRawString*>(name), name->hash());
- }
-}
-
-
void Scope::SetIllegalRedeclaration(Expression* expression) {
// Record only the first illegal redeclaration.
if (!HasIllegalRedeclaration()) {
// If it does, and if it is not copied into the context object, it must
// receive the highest parameter index for that parameter; thus iteration
// order is relevant!
- //
- // If hasParameterExpressions is true, parameters are redeclared during
- // desugaring, and must not be allocated here.
- if (!has_parameter_expressions_) {
- for (int i = params_.length() - 1; i >= 0; --i) {
- Variable* var = params_[i];
- if (var == rest_parameter_) continue;
-
- DCHECK(var->scope() == this);
- if (uses_sloppy_arguments || has_forced_context_allocation()) {
- // Force context allocation of the parameter.
- var->ForceContextAllocation();
- }
- AllocateParameter(var, i);
+ for (int i = params_.length() - 1; i >= 0; --i) {
+ Variable* var = params_[i];
+ if (var == rest_parameter_) continue;
+
+ DCHECK(var->scope() == this);
+ if (uses_sloppy_arguments || has_forced_context_allocation()) {
+ // Force context allocation of the parameter.
+ var->ForceContextAllocation();
}
+ AllocateParameter(var, i);
}
}
// parameters the rightmost one 'wins'. However, the implementation
// expects all parameters to be declared and from left to right.
Variable* DeclareParameter(const AstRawString* name, VariableMode mode,
- bool is_rest, bool* is_duplicate, int pos);
+ bool is_rest, bool* is_duplicate);
// Declare a local variable in this scope. If the variable has been
// declared before, the previously declared variable is returned.
// the scope; see codegen.cc:ProcessDeclarations.
void AddDeclaration(Declaration* declaration);
- // Formal parameters may be re-declared as lexical declarations in order to
- // support TDZ semantics specified in ECMAScript 6.
- void UndeclareParametersForExpressions();
-
// ---------------------------------------------------------------------------
// Illegal redeclaration support.
return params_[index];
}
- // TODO(caitp): This probably won't work when BindingPatterns are supported
- // in function parameters. Need a better way.
- int parameter_position(int index) const {
- DCHECK(is_function_scope());
- return param_positions_[index];
- }
-
// Returns the default function arity --- does not include rest parameters.
int default_function_length() const {
int count = params_.length();
ZoneList<Variable*> temps_;
// Parameter list in source order.
ZoneList<Variable*> params_;
- ZoneList<int> param_positions_;
// Variables that must be looked up dynamically.
DynamicScopePart* dynamics_;
// Unresolved variables referred to from this scope.
Variable* rest_parameter_;
int rest_index_;
- bool has_parameter_expressions_;
-
// Serialized scope info support.
Handle<ScopeInfo> scope_info_;
bool already_resolved() { return already_resolved_; }
Handle<String> name() const { return name_->string(); }
const AstRawString* raw_name() const { return name_; }
VariableMode mode() const { return mode_; }
- void set_mode(VariableMode mode) {
- // Don't use this unless you have a very good reason
- mode_ = mode;
- }
bool has_forced_context_allocation() const {
return force_context_allocation_;
}
+++ /dev/null
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --expose-debug-as debug --harmony-default-parameters
-
-// Get the Debug object exposed from the debug context global object.
-Debug = debug.Debug
-
-listenerComplete = false;
-breakPointCount = 0;
-
-function listener(event, exec_state, event_data, data) {
- if (event == Debug.DebugEvent.Break) {
- breakPointCount++;
- if (breakPointCount == 1) {
- // Break point in initializer for parameter `a`, invoked by
- // initializer for parameter `b`
- assertEquals('default', exec_state.frame(1).evaluate('mode').value());
-
- // initializer for `b` can't refer to `b`
- assertThrows(function() {
- return exec_state.frame(1).evaluate('b').value();
- }, ReferenceError);
-
- assertThrows(function() {
- return exec_state.frame(1).evaluate('c');
- }, ReferenceError);
- } else if (breakPointCount == 2) {
- // Break point in IIFE initializer for parameter `c`
- assertEquals('modeFn', exec_state.frame(1).evaluate('a.name').value());
- assertEquals('default', exec_state.frame(1).evaluate('b').value());
- assertThrows(function() {
- return exec_state.frame(1).evaluate('c');
- }, ReferenceError);
- } else if (breakPointCount == 3) {
- // Break point in function body --- `c` parameter is shadowed
- assertEquals('modeFn', exec_state.frame(0).evaluate('a.name').value());
- assertEquals('default', exec_state.frame(0).evaluate('b').value());
- // TODO(caitp): fix scoping so that parameter `c` can be shadowed by vars
- //assertEquals(true, exec_state.frame(0).evaluate('c').value());
- }
- }
-};
-
-// Add the debug event listener.
-Debug.setListener(listener);
-
-function f(a = function modeFn(mode) {
- debugger;
- return mode;
- },
- b = a("default"),
- c = (function() {
- debugger;
- })()) {
- // TODO(caitp): fix scoping so that parameter `c` can be shadowed by vars
- //var c = true;
- debugger;
-};
-
-f();
-
-// Make sure that the debug event listener vas invoked.
-assertEquals(3, breakPointCount);
+++ /dev/null
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-default-parameters --min-preparse-length=0
-
-var i = 0;
-function f(handler = function(b) { return b + "#" + (++i); }, b = "red") {
- return handler(b);
-}
-
-assertEquals([
- "blue#1",
- "red#2",
- "red",
- "yellow#3"
-], [
- f(undefined, "blue"),
- f(),
- f(function(b) { return b; }),
- f(undefined, "yellow")
-]);
+++ /dev/null
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --harmony-default-parameters --harmony-arrow-functions
-
-function return_specified() { return "specified"; }
-
-var method_returns_specified = {
- method() { return "specified"; }
-};
-
-
-(function testDefaultFunctions() {
- function optional_function(handler = function() { }) {
- assertEquals("function", typeof handler);
-
- // TODO(caitp): infer function name correctly
- // (https://code.google.com/p/v8/issues/detail?id=3699)
- // assertEquals("handler", handler.name);
-
- return handler();
- }
- assertEquals(undefined, optional_function());
- assertEquals(undefined, optional_function(undefined));
- assertEquals("specified", optional_function(return_specified));
-})();
-
-
-(function testDefaultFunctionReferencesParameters() {
- function fn1(handler = function() { return value; }, value) {
- return handler();
- }
- assertEquals(undefined, fn1());
- assertEquals(undefined, fn1(undefined, undefined));
- assertEquals(1, fn1(undefined, 1));
-
- function fn2(value, handler = function() { return value; }) {
- return handler();
- }
- assertEquals(undefined, fn2());
- assertEquals(undefined, fn2(undefined));
- assertEquals(1, fn2(1));
-})();
-
-
-(function testDefaultObjects() {
- function optional_object(object = { method() { return "method"; } }) {
- assertEquals("object", typeof object);
-
- assertEquals("function", typeof object.method);
- return object.method();
- }
-
- assertEquals("method", optional_object());
- assertEquals("method", optional_object(undefined));
- assertEquals("specified", optional_object(method_returns_specified));
-
-
- assertEquals(4, (function(x = { a: 4 }) { return x.a; })());
- assertEquals(5, (function(x, y = { a: x }) { return y.a; })(5));
- assertEquals(6, (function(x, y = { a: eval("x") }) { return y.a; })(6));
-})();
-
-
-// TDZ
-
-(function testReferencesUninitializedParameter() {
- assertThrows(function(a = b, b) {}, ReferenceError);
-})();
-
-
-(function testEvalReferencesUninitializedParameter() {
- assertThrows( function(x = { a: y }, y) { return x.a; }, ReferenceError);
- assertThrows(function(a = eval("b"), b = 0) { return a; }, ReferenceError);
- assertThrows(
- function(x = { a: eval("y") }, y) { return x.a; }, ReferenceError);
-})();
-
-
-(function testReferencesInitializedParameter() {
- assertEquals(1, (function(a = 1, b = a) { return b; })());
-})();
-
-
-// Scoping
-//
-// TODO(caitp): fix scoping --- var declarations in function body can't be
-// resolved in formal parameters
-// assertThrows(function referencesVariableBodyDeclaration(a = body_var) {
-// var body_var = true;
-// return a;
-// }, ReferenceError);
-
-
-// TODO(caitp): default function length does not include any parameters
-// following the first optional parameter
-// assertEquals(0, (function(a = 1) {}).length);
-// assertEquals(1, (function(a, b = 1) {}).length);
-// assertEquals(2, (function(a, b, c = 1) {}).length);
-// assertEquals(3, (function(a, b, c, d = 1) {}).length);
-// assertEquals(1, (function(a, b = 1, c, d = 1) {}).length);
-
-
-(function testInitializerReferencesThis() {
- var O = {};
- function fn(x = this) { return x; }
- assertEquals(O, fn.call(O));
-
- function fn2(x = () => this) { return x(); }
- assertEquals(O, fn2.call(O));
-})();
-
-
-(function testInitializerReferencesSelf() {
- function fn(x, y = fn) { return x ? y(false) + 1 : 0 }
- assertEquals(1, fn(true));
-})();
-
-
-(function testInitializerEvalParameter() {
- assertEquals(7, (function(x, y = eval("x")) { return y; })(7));
- assertEquals(9, (function(x = () => eval("y"), y = 9) { return x(); })());
-})();
-
-
-(function testContextAllocatedUsedInBody() {
- assertEquals("Monkey!Monkey!Monkey!", (function(x, y = eval("x")) {
- return "Mon" + x + "Mon" + eval("y") + "Mon" + y;
- })("key!"));
- assertEquals("Monkey!", (function(x = "Mon", y = "key!") {
- return eval("x") + eval("y");
- })());
-})();
-
-
-(function testContextAllocatedEscapesFunction() {
- assertEquals("Monkey!", (function(x = "Monkey!") {
- return function() {
- return x;
- };
- })()());
-})();