}
-bool CompilationInfo::is_simple_parameter_list() {
- return scope()->is_simple_parameter_list();
+bool CompilationInfo::has_simple_parameters() {
+ return scope()->has_simple_parameters();
}
void PrintAstForTesting();
#endif
- bool is_simple_parameter_list();
+ bool has_simple_parameters();
Handle<Code> GenerateCodeStub();
Handle<JSObject> Factory::NewArgumentsObject(Handle<JSFunction> callee,
int length) {
bool strict_mode_callee = is_strict(callee->shared()->language_mode()) ||
- !callee->is_simple_parameter_list();
+ !callee->has_simple_parameters();
Handle<Map> map = strict_mode_callee ? isolate()->strict_arguments_map()
: isolate()->sloppy_arguments_map();
-
AllocationSiteUsageContext context(isolate(), Handle<AllocationSite>(),
false);
DCHECK(!isolate()->has_pending_exception());
// The stub will rewrite receiver and parameter count if the previous
// stack frame was an arguments adapter frame.
ArgumentsAccessStub::Type type;
- if (is_strict(language_mode()) || !is_simple_parameter_list()) {
+ if (is_strict(language_mode()) || !has_simple_parameters()) {
type = ArgumentsAccessStub::NEW_STRICT;
} else if (function()->has_duplicate_parameters()) {
type = ArgumentsAccessStub::NEW_SLOPPY_SLOW;
// The stub will rewrite receiver and parameter count if the previous
// stack frame was an arguments adapter frame.
ArgumentsAccessStub::Type type;
- if (is_strict(language_mode()) || !is_simple_parameter_list()) {
+ if (is_strict(language_mode()) || !has_simple_parameters()) {
type = ArgumentsAccessStub::NEW_STRICT;
} else if (function()->has_duplicate_parameters()) {
type = ArgumentsAccessStub::NEW_SLOPPY_SLOW;
bool is_eval() { return info_->is_eval(); }
bool is_native() { return info_->is_native(); }
LanguageMode language_mode() { return function()->language_mode(); }
- bool is_simple_parameter_list() { return info_->is_simple_parameter_list(); }
+ bool has_simple_parameters() { return info_->has_simple_parameters(); }
FunctionLiteral* function() { return info_->function(); }
Scope* scope() { return scope_; }
// The stub will rewrite receiver and parameter count if the previous
// stack frame was an arguments adapter frame.
ArgumentsAccessStub::Type type;
- if (is_strict(language_mode()) || !is_simple_parameter_list()) {
+ if (is_strict(language_mode()) || !has_simple_parameters()) {
type = ArgumentsAccessStub::NEW_STRICT;
} else if (function()->has_duplicate_parameters()) {
type = ArgumentsAccessStub::NEW_SLOPPY_SLOW;
// The stub will rewrite receiever and parameter count if the previous
// stack frame was an arguments adapter frame.
ArgumentsAccessStub::Type type;
- if (is_strict(language_mode()) || !is_simple_parameter_list()) {
+ if (is_strict(language_mode()) || !has_simple_parameters()) {
type = ArgumentsAccessStub::NEW_STRICT;
} else if (function()->has_duplicate_parameters()) {
type = ArgumentsAccessStub::NEW_SLOPPY_SLOW;
// The stub will rewrite receiever and parameter count if the previous
// stack frame was an arguments adapter frame.
ArgumentsAccessStub::Type type;
- if (is_strict(language_mode()) || !is_simple_parameter_list()) {
+ if (is_strict(language_mode()) || !has_simple_parameters()) {
type = ArgumentsAccessStub::NEW_STRICT;
} else if (function()->has_duplicate_parameters()) {
type = ArgumentsAccessStub::NEW_SLOPPY_SLOW;
// The stub will rewrite receiver and parameter count if the previous
// stack frame was an arguments adapter frame.
ArgumentsAccessStub::Type type;
- if (is_strict(language_mode()) || !is_simple_parameter_list()) {
+ if (is_strict(language_mode()) || !has_simple_parameters()) {
type = ArgumentsAccessStub::NEW_STRICT;
} else if (function()->has_duplicate_parameters()) {
type = ArgumentsAccessStub::NEW_SLOPPY_SLOW;
// stack frame was an arguments adapter frame.
ArgumentsAccessStub::Type type;
- if (is_strict(language_mode()) || !is_simple_parameter_list()) {
+ if (is_strict(language_mode()) || !has_simple_parameters()) {
type = ArgumentsAccessStub::NEW_STRICT;
} else if (function()->has_duplicate_parameters()) {
type = ArgumentsAccessStub::NEW_SLOPPY_SLOW;
// The stub will rewrite receiver and parameter count if the previous
// stack frame was an arguments adapter frame.
ArgumentsAccessStub::Type type;
- if (is_strict(language_mode()) || !is_simple_parameter_list()) {
+ if (is_strict(language_mode()) || !has_simple_parameters()) {
type = ArgumentsAccessStub::NEW_STRICT;
} else if (function()->has_duplicate_parameters()) {
type = ArgumentsAccessStub::NEW_SLOPPY_SLOW;
}
-bool SharedFunctionInfo::is_simple_parameter_list() {
- return scope_info()->IsSimpleParameterList();
+bool SharedFunctionInfo::has_simple_parameters() {
+ return scope_info()->HasSimpleParameters();
}
}
-bool JSFunction::is_simple_parameter_list() {
- return shared()->is_simple_parameter_list();
+bool JSFunction::has_simple_parameters() {
+ return shared()->has_simple_parameters();
}
// Return if this is a nested function within an asm module scope.
bool IsAsmFunction() { return AsmFunctionField::decode(Flags()); }
- bool IsSimpleParameterList() {
- return IsSimpleParameterListField::decode(Flags());
+ bool HasSimpleParameters() {
+ return HasSimpleParametersField::decode(Flags());
}
// Return the function_name if present.
class AsmModuleField : public BitField<bool, FunctionVariableMode::kNext, 1> {
};
class AsmFunctionField : public BitField<bool, AsmModuleField::kNext, 1> {};
- class IsSimpleParameterListField
+ class HasSimpleParametersField
: public BitField<bool, AsmFunctionField::kNext, 1> {};
class FunctionKindField
- : public BitField<FunctionKind, IsSimpleParameterListField::kNext, 8> {};
+ : public BitField<FunctionKind, HasSimpleParametersField::kNext, 8> {};
// BitFields representing the encoded information for context locals in the
// ContextLocalInfoEntries part.
// Calculate the number of in-object properties.
int CalculateInObjectProperties();
- inline bool is_simple_parameter_list();
+ inline bool has_simple_parameters();
// Initialize a SharedFunctionInfo from a parsed function literal.
static void InitFromFunctionLiteral(Handle<SharedFunctionInfo> shared_info,
// Returns `false` if formal parameters include rest parameters, optional
// parameters, or destructuring parameters.
// TODO(caitp): make this a flag set during parsing
- inline bool is_simple_parameter_list();
+ inline bool has_simple_parameters();
// [next_function_link]: Links functions into various lists, e.g. the list
// of optimized functions hanging off the native_context. The CodeFlusher
*duplicate_loc = classifier.duplicate_formal_parameter_error().location;
}
}
+ DCHECK_EQ(parameters->is_simple, parameters->scope->has_simple_parameters());
}
Object** parameters,
int argument_count) {
CHECK(!IsSubclassConstructor(callee->shared()->kind()));
- DCHECK(callee->is_simple_parameter_list());
+ DCHECK(callee->has_simple_parameters());
Handle<JSObject> result =
isolate->factory()->NewArgumentsObject(callee, argument_count);
Object** parameters = reinterpret_cast<Object**>(frame->GetParameterSlot(-1));
return (is_strict(callee->shared()->language_mode()) ||
- !callee->is_simple_parameter_list())
+ !callee->has_simple_parameters())
? *NewStrictArguments(isolate, callee, parameters, argument_count)
: *NewSloppyArguments(isolate, callee, parameters, argument_count);
}
DCHECK_EQ(scope->ContextLocalCount(), context_local_count);
DCHECK_EQ(scope->ContextGlobalCount(), context_global_count);
- bool simple_parameter_list =
- scope->is_function_scope() ? scope->is_simple_parameter_list() : true;
-
// Determine use and location of the "this" binding if it is present.
VariableAllocationInfo receiver_info;
if (scope->has_this_declaration()) {
Factory* factory = isolate->factory();
Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length);
+ bool has_simple_parameters =
+ scope->is_function_scope() && scope->has_simple_parameters();
+
// Encode the flags.
int flags = ScopeTypeField::encode(scope->scope_type()) |
CallsEvalField::encode(scope->calls_eval()) |
FunctionVariableMode::encode(function_variable_mode) |
AsmModuleField::encode(scope->asm_module()) |
AsmFunctionField::encode(scope->asm_function()) |
- IsSimpleParameterListField::encode(simple_parameter_list) |
+ HasSimpleParametersField::encode(has_simple_parameters) |
FunctionKindField::encode(scope->function_kind());
scope_info->SetFlags(flags);
scope_info->SetParameterCount(parameter_count);
const int context_local_count = 1;
const int context_global_count = 0;
const int strong_mode_free_variable_count = 0;
- const bool simple_parameter_list = true;
+ const bool has_simple_parameters = true;
const VariableAllocationInfo receiver_info = CONTEXT;
const VariableAllocationInfo function_name_info = NONE;
const VariableMode function_variable_mode = VAR;
FunctionVariableField::encode(function_name_info) |
FunctionVariableMode::encode(function_variable_mode) |
AsmModuleField::encode(false) | AsmFunctionField::encode(false) |
- IsSimpleParameterListField::encode(simple_parameter_list) |
+ HasSimpleParametersField::encode(has_simple_parameters) |
FunctionKindField::encode(FunctionKind::kNormalFunction);
scope_info->SetFlags(flags);
scope_info->SetParameterCount(parameter_count);
num_heap_slots_ = 0;
num_global_slots_ = 0;
num_modules_ = 0;
- module_var_ = NULL,
+ module_var_ = NULL;
+ has_simple_parameters_ = true;
rest_parameter_ = NULL;
rest_index_ = -1;
scope_info_ = scope_info;
Variable* var;
if (mode == TEMPORARY) {
var = NewTemporary(name);
+ has_simple_parameters_ = false;
} else {
var = variables_.Declare(this, name, mode, Variable::NORMAL,
kCreatedInitialized);
DCHECK_NULL(rest_parameter_);
rest_parameter_ = var;
rest_index_ = num_parameters();
+ has_simple_parameters_ = false;
}
params_.Add(var, zone());
return var;
// In strict mode 'arguments' does not alias formal parameters.
// Therefore in strict mode we allocate parameters as if 'arguments'
// were not used.
- uses_sloppy_arguments = is_sloppy(language_mode());
+ // If the parameter list is not simple, arguments isn't sloppy either.
+ uses_sloppy_arguments =
+ is_sloppy(language_mode()) && has_simple_parameters();
}
if (rest_parameter_ && !MustAllocate(rest_parameter_)) {
return rest_index_ >= 0;
}
- bool is_simple_parameter_list() const {
+ bool has_simple_parameters() const {
DCHECK(is_function_scope());
- if (rest_index_ >= 0) return false;
- return true;
+ return has_simple_parameters_;
}
// The local variable 'arguments' if we need to allocate it; NULL otherwise.
// For module scopes, the host scope's temporary variable binding this module.
Variable* module_var_;
- // Rest parameter
+ // Info about the parameter list of a function.
+ bool has_simple_parameters_;
Variable* rest_parameter_;
int rest_index_;
}());
+(function TestArgumentsForNonSimpleParameters() {
+ function f1({}, x) { arguments[1] = 0; return x }
+ assertEquals(6, f1({}, 6));
+ function f2({}, x) { x = 2; return arguments[1] }
+ assertEquals(7, f2({}, 7));
+ function f3(x, {}) { arguments[0] = 0; return x }
+ assertEquals(6, f3(6, {}));
+ function f4(x, {}) { x = 2; return arguments[0] }
+ assertEquals(7, f4(7, {}));
+ function f5(x, ...a) { arguments[0] = 0; return x }
+ assertEquals(6, f5(6, {}));
+ function f6(x, ...a) { x = 2; return arguments[0] }
+ assertEquals(6, f6(6, {}));
+ function f7({a: x}) { x = 2; return arguments[0].a }
+ assertEquals(5, f7({a: 5}));
+ function f8(x, ...a) { a = []; return arguments[1] }
+ assertEquals(6, f8(5, 6));
+ // TODO(caitp, rossberg): add cases for default parameters.
+}());
+
+
(function TestForInOfTDZ() {
assertThrows("'use strict'; let x = {}; for (let [x, y] of {x});", ReferenceError);
assertThrows("'use strict'; let x = {}; for (let [y, x] of {x});", ReferenceError);