Reviewers: adamk,
Description:
[es6] Use strict arguments objects for destructured parameters
Plus some renaming for consistency.
[email protected]
BUG=v8:811
LOG=N
Please review this at https://codereview.chromium.org/1278783002/
Base URL: https://chromium.googlesource.com/v8/v8.git@master
Affected files (+57, -31 lines):
M src/compiler.h
M src/compiler.cc
M src/factory.cc
M src/full-codegen/full-codegen.h
M src/full-codegen/ia32/full-codegen-ia32.cc
M src/objects.h
M src/objects-inl.h
M src/parser.cc
M src/runtime/runtime-scopes.cc
M src/scopeinfo.cc
M src/scopes.h
M src/scopes.cc
M test/mjsunit/harmony/destructuring.js
Index: src/compiler.cc
diff --git a/src/compiler.cc b/src/compiler.cc
index
ccf41716f6c9e9cb3a2237066421c8b3c7868d36..ede006c04cf27d7cfb4709a31c554efb809a2bc0
100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -222,8 +222,8 @@ void CompilationInfo::EnsureFeedbackVector() {
}
-bool CompilationInfo::is_simple_parameter_list() {
- return scope()->is_simple_parameter_list();
+bool CompilationInfo::has_simple_parameters() {
+ return scope()->has_simple_parameters();
}
Index: src/compiler.h
diff --git a/src/compiler.h b/src/compiler.h
index
df81a4f5d27790dbdef89c20e013c29c08ceaf0a..78ae812970ca19658b8e67c5fac62effed7dfa21
100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -400,7 +400,7 @@ class CompilationInfo {
void PrintAstForTesting();
#endif
- bool is_simple_parameter_list();
+ bool has_simple_parameters();
Handle<Code> GenerateCodeStub();
Index: src/factory.cc
diff --git a/src/factory.cc b/src/factory.cc
index
8944905d96190d991e4051306a471ae43cc17d91..05cb259602edb00bcc9427dd75e69b82f9e30d55
100644
--- a/src/factory.cc
+++ b/src/factory.cc
@@ -2348,10 +2348,9 @@ Handle<DebugInfo>
Factory::NewDebugInfo(Handle<SharedFunctionInfo> shared) {
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());
Index: src/full-codegen/full-codegen.h
diff --git a/src/full-codegen/full-codegen.h
b/src/full-codegen/full-codegen.h
index
6761bda27192f84fc25199a5ab5c010449d5dda0..5406ccd1fc1150d4fc29c39101476ebda97cb6ec
100644
--- a/src/full-codegen/full-codegen.h
+++ b/src/full-codegen/full-codegen.h
@@ -700,7 +700,7 @@ class FullCodeGenerator: public AstVisitor {
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_; }
Index: src/full-codegen/ia32/full-codegen-ia32.cc
diff --git a/src/full-codegen/ia32/full-codegen-ia32.cc
b/src/full-codegen/ia32/full-codegen-ia32.cc
index
6c1ac09969f99a4b59893ce23b36882d9a830c0c..d9ca3bd0c4d74bbf5141997438d4a7420ae99838
100644
--- a/src/full-codegen/ia32/full-codegen-ia32.cc
+++ b/src/full-codegen/ia32/full-codegen-ia32.cc
@@ -320,7 +320,7 @@ void FullCodeGenerator::Generate() {
// 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;
Index: src/objects-inl.h
diff --git a/src/objects-inl.h b/src/objects-inl.h
index
3a9fe2991decc352c34f79a0635ce1968a57539f..d8175c79812c8948f9bc450f4cf72721f13af075
100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -5378,8 +5378,8 @@ bool SharedFunctionInfo::is_compiled() {
}
-bool SharedFunctionInfo::is_simple_parameter_list() {
- return scope_info()->IsSimpleParameterList();
+bool SharedFunctionInfo::has_simple_parameters() {
+ return scope_info()->HasSimpleParameters();
}
@@ -5685,8 +5685,8 @@ bool JSFunction::is_compiled() {
}
-bool JSFunction::is_simple_parameter_list() {
- return shared()->is_simple_parameter_list();
+bool JSFunction::has_simple_parameters() {
+ return shared()->has_simple_parameters();
}
Index: src/objects.h
diff --git a/src/objects.h b/src/objects.h
index
6d052ef3a6d43cb43a2e874393298c7897e2bfe3..e3a8e03d4a891de8c7751e865ca7eb79d7deb440
100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -3884,8 +3884,8 @@ class ScopeInfo : public FixedArray {
// 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.
@@ -4084,10 +4084,10 @@ class ScopeInfo : public FixedArray {
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.
@@ -6628,7 +6628,7 @@ class SharedFunctionInfo: public HeapObject {
// 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,
@@ -7143,7 +7143,7 @@ class JSFunction: public JSObject {
// 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
Index: src/parser.cc
diff --git a/src/parser.cc b/src/parser.cc
index
6a0838e067091c62390bc5412631004cf15857f2..45202cb3a82b922c7d487061cfff03578cc3a3c9
100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -3926,6 +3926,7 @@ void
ParserTraits::ParseArrowFunctionFormalParameterList(
*duplicate_loc =
classifier.duplicate_formal_parameter_error().location;
}
}
+ DCHECK_EQ(parameters->is_simple,
parameters->scope->has_simple_parameters());
}
Index: src/runtime/runtime-scopes.cc
diff --git a/src/runtime/runtime-scopes.cc b/src/runtime/runtime-scopes.cc
index
ff7e783393081cbe731a8d5f265a5b0fa852b773..be13a14d4f078f419db5f8045f3c794f6078ab57
100644
--- a/src/runtime/runtime-scopes.cc
+++ b/src/runtime/runtime-scopes.cc
@@ -397,7 +397,7 @@ static Handle<JSObject> NewSloppyArguments(Isolate*
isolate,
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);
@@ -518,7 +518,7 @@ RUNTIME_FUNCTION(Runtime_NewArguments) {
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);
}
Index: src/scopeinfo.cc
diff --git a/src/scopeinfo.cc b/src/scopeinfo.cc
index
e490fd9ce48f11eff84aa20f143f852dfea3d7ac..e53f36d27439aef1874b1be7df1637225dffa33f
100644
--- a/src/scopeinfo.cc
+++ b/src/scopeinfo.cc
@@ -34,9 +34,6 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate,
Zone* zone,
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()) {
@@ -85,6 +82,9 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate,
Zone* zone,
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()) |
@@ -94,7 +94,7 @@ Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate,
Zone* zone,
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);
@@ -224,7 +224,7 @@ Handle<ScopeInfo>
ScopeInfo::CreateGlobalThisBinding(Isolate* isolate) {
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;
@@ -248,7 +248,7 @@ Handle<ScopeInfo>
ScopeInfo::CreateGlobalThisBinding(Isolate* isolate) {
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);
Index: src/scopes.cc
diff --git a/src/scopes.cc b/src/scopes.cc
index
319aca518ed69187dc29cc817c58f9266b2a8700..8ce28bd6aba130598ff24eb39df95f3967a37e4d
100644
--- a/src/scopes.cc
+++ b/src/scopes.cc
@@ -180,7 +180,8 @@ void Scope::SetDefaults(ScopeType scope_type, Scope*
outer_scope,
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;
@@ -468,6 +469,7 @@ Variable* Scope::DeclareParameter(const AstRawString*
name, VariableMode mode,
Variable* var;
if (mode == TEMPORARY) {
var = NewTemporary(name);
+ has_simple_parameters_ = false;
} else {
var = variables_.Declare(this, name, mode, Variable::NORMAL,
kCreatedInitialized);
@@ -478,6 +480,7 @@ Variable* Scope::DeclareParameter(const AstRawString*
name, VariableMode mode,
DCHECK_NULL(rest_parameter_);
rest_parameter_ = var;
rest_index_ = num_parameters();
+ has_simple_parameters_ = false;
}
params_.Add(var, zone());
return var;
@@ -1399,7 +1402,9 @@ void Scope::AllocateParameterLocals(Isolate* isolate)
{
// 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_)) {
Index: src/scopes.h
diff --git a/src/scopes.h b/src/scopes.h
index
f48b3ae7111a1c6c841d641d671dff7622f1fac8..acfad4cf1605ac1f4b152636093841a303846147
100644
--- a/src/scopes.h
+++ b/src/scopes.h
@@ -389,10 +389,9 @@ class Scope: public ZoneObject {
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.
@@ -632,7 +631,8 @@ class Scope: public ZoneObject {
// 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_;
Index: test/mjsunit/harmony/destructuring.js
diff --git a/test/mjsunit/harmony/destructuring.js
b/test/mjsunit/harmony/destructuring.js
index
0bbaf26285932fd527cedad0c058fab591eae9e4..2a525faccbeab5ed5c3b3ccd95c23092677286f0
100644
--- a/test/mjsunit/harmony/destructuring.js
+++ b/test/mjsunit/harmony/destructuring.js
@@ -918,6 +918,27 @@
}());
+(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);
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.